Merge sources from S-Core's RSA git (release) 2.0alpha master 2.0_alpha
authorJenkins <taeyoung2.son@samsung.com>
Tue, 18 Sep 2012 04:27:40 +0000 (13:27 +0900)
committerJenkins <taeyoung2.son@samsung.com>
Tue, 18 Sep 2012 04:27:40 +0000 (13:27 +0900)
Change-Id: Id40e89a773ceb063b1b0a84fcc651d63cf869b98

471 files changed:
org.tizen.common.connection/META-INF/MANIFEST.MF
org.tizen.common.connection/OSGI-INF/l10n/bundle.properties [new file with mode: 0644]
org.tizen.common.connection/build.properties
org.tizen.common.connection/icons/Emulator_stop.gif [deleted file]
org.tizen.common.connection/icons/connection_explorer.gif [moved from org.tizen.common.connection/icons/Connection Explorer.gif with 100% similarity]
org.tizen.common.connection/icons/emulator_manager.gif [moved from org.tizen.common.connection/icons/Emulator_start.gif with 100% similarity]
org.tizen.common.connection/icons/log/add_tab.png [moved from org.tizen.common.connection/icons/log/Add tab.png with 100% similarity]
org.tizen.common.connection/icons/log/clear_log.png [moved from org.tizen.common.connection/icons/log/Clear Log.png with 100% similarity]
org.tizen.common.connection/icons/log/edit_tab.png [moved from org.tizen.common.connection/icons/log/Edit tab.png with 100% similarity]
org.tizen.common.connection/icons/log/export_log.png [moved from org.tizen.common.connection/icons/log/Export Log.png with 100% similarity]
org.tizen.common.connection/icons/log/logview.gif [moved from org.tizen.common.connection/icons/log/Log View.gif with 100% similarity]
org.tizen.common.connection/icons/log/remove_tab.png [moved from org.tizen.common.connection/icons/log/Remove tab.png with 100% similarity]
org.tizen.common.connection/icons/log/scroll_lock.png [new file with mode: 0644]
org.tizen.common.connection/plugin.xml
org.tizen.common.connection/src/org/tizen/common/connection/ConnectionPlugin.java [changed mode: 0644->0755]
org.tizen.common.connection/src/org/tizen/common/connection/ConnectionPluginSurrogate.java [new file with mode: 0644]
org.tizen.common.connection/src/org/tizen/common/connection/ddmuilib/FileDialogUtils.java
org.tizen.common.connection/src/org/tizen/common/connection/debugtools/DebugTool.java
org.tizen.common.connection/src/org/tizen/common/connection/debugtools/ToolsInstall.java [changed mode: 0644->0755]
org.tizen.common.connection/src/org/tizen/common/connection/debugtools/ToolsInstallMessages.properties
org.tizen.common.connection/src/org/tizen/common/connection/explorer/ConnectionExplorerContentProvider.java
org.tizen.common.connection/src/org/tizen/common/connection/explorer/ConnectionExplorerLabelProvider.java [changed mode: 0644->0755]
org.tizen.common.connection/src/org/tizen/common/connection/explorer/ConnectionExplorerPanel.java [changed mode: 0644->0755]
org.tizen.common.connection/src/org/tizen/common/connection/explorer/Messages.java [changed mode: 0644->0755]
org.tizen.common.connection/src/org/tizen/common/connection/explorer/messages.properties
org.tizen.common.connection/src/org/tizen/common/connection/log/AddViewDialog.java [changed mode: 0644->0755]
org.tizen.common.connection/src/org/tizen/common/connection/log/LogColors.java
org.tizen.common.connection/src/org/tizen/common/connection/log/LogPanel.java [changed mode: 0644->0755]
org.tizen.common.connection/src/org/tizen/common/connection/log/LogTab.java
org.tizen.common.connection/src/org/tizen/common/connection/log/LogUIMessages.properties
org.tizen.common.connection/src/org/tizen/common/connection/properties/ConnectionExplorerPermissionPropertyPages.java [changed mode: 0644->0755]
org.tizen.common.connection/src/org/tizen/common/connection/sdblib/dnd/FileEntryDropAdapter.java
org.tizen.common.connection/src/org/tizen/common/connection/ui/ConnectionExplorer.java [changed mode: 0644->0755]
org.tizen.common.connection/src/org/tizen/common/connection/ui/ConnectionUIMessages.java [new file with mode: 0644]
org.tizen.common.connection/src/org/tizen/common/connection/ui/ConnectionUIMessages.properties [new file with mode: 0644]
org.tizen.common.connection/src/org/tizen/common/connection/ui/LogView.java
org.tizen.common.connection/src/org/tizen/common/connection/ui/TizenRemoteFileDialog.java
org.tizen.common.connection/src/org/tizen/common/connection/ui/TizenRemoteFileLabelProvider.java [changed mode: 0644->0755]
org.tizen.common.externals/.classpath [new file with mode: 0644]
org.tizen.common.externals/.project [new file with mode: 0644]
org.tizen.common.externals/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
org.tizen.common.externals/META-INF/MANIFEST.MF [new file with mode: 0644]
org.tizen.common.externals/OSGI-INF/l10n/bundle.properties [new file with mode: 0644]
org.tizen.common.externals/about.html [new file with mode: 0644]
org.tizen.common.externals/about_files/LICENSE-2.0.htm [new file with mode: 0644]
org.tizen.common.externals/about_files/epl-v10.html [new file with mode: 0644]
org.tizen.common.externals/build.properties [new file with mode: 0644]
org.tizen.common.externals/resources/opal.properties [new file with mode: 0644]
org.tizen.common.externals/resources/opal_de_DE.properties [new file with mode: 0644]
org.tizen.common.externals/resources/opal_es_ES.properties [new file with mode: 0644]
org.tizen.common.externals/resources/opal_fr_FR.properties [new file with mode: 0644]
org.tizen.common.externals/resources/opal_it_IT.properties [new file with mode: 0644]
org.tizen.common.externals/resources/opal_pl_PL.properties [new file with mode: 0644]
org.tizen.common.externals/resources/opal_pt_BR.properties [new file with mode: 0644]
org.tizen.common.externals/resources/opal_zh_CN.properties [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/OpalItem.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/angles/AngleSlider.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/brushedMetalComposite/BrushedMetalComposite.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/checkBoxGroup/CheckBoxGroup.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnBrowserWidget.java [new file with mode: 0755]
org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnItem.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/flatButton/FlatButton.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/gradientComposite/GradientComposite.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/header/Header.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/heapManager/HeapManager.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/horizontalSpinner/HorizontalSpinner.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ISItem.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ImageSelector.java [new file with mode: 0755]
org.tizen.common.externals/src/org/mihalis/opal/infinitePanel/InfiniteProgressPanel.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DLItem.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DualList.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/launcher/LLabel.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/launcher/Launcher.java [new file with mode: 0755]
org.tizen.common.externals/src/org/mihalis/opal/launcher/LauncherItem.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialog.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialogVerifier.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoice.java [new file with mode: 0755]
org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoiceSelectionListener.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/notify/Notifier.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/notify/NotifierColors.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/notify/NotifierColorsFactory.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/opalDialog/ChoiceItem.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/opalDialog/ChoiceWidget.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/opalDialog/Dialog.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/opalDialog/DialogArea.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/opalDialog/FooterArea.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/opalDialog/MessageArea.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/panels/BlurredPanel.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/panels/DarkPanel.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWContainer.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWGroup.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWRow.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWRowGroup.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWTab.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWTabContainer.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PreferenceWindow.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/ValueAndAssociatedWidgets.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfEquals.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfNotEquals.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfTrue.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/Enabler.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWButton.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWCheckbox.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWChooser.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWColorChooser.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWCombo.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWDirectoryChooser.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFileChooser.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFloatText.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFontChooser.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWIntegerText.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWLabel.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWPasswordText.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWRadio.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWScale.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWSeparator.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWSpinner.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWStringText.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWText.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWTextarea.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWURLText.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWWidget.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/promptSupport/BaseFocusControlListener.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/promptSupport/CComboFocusControlListener.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/promptSupport/ComboFocusControlListener.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/promptSupport/FocusControlListenerFactory.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/promptSupport/PromptSupport.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/promptSupport/StyledTextFocusControlListener.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/promptSupport/TextFocusControlListener.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/rangeSlider/RangeSlider.java [new file with mode: 0755]
org.tizen.common.externals/src/org/mihalis/opal/switchButton/SwitchButton.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/textAssist/TextAssist.java [new file with mode: 0755]
org.tizen.common.externals/src/org/mihalis/opal/textAssist/TextAssistContentProvider.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/tipOfTheDay/TipOfTheDay.java [new file with mode: 0755]
org.tizen.common.externals/src/org/mihalis/opal/titledSeparator/TitledSeparator.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/DownUpAppearTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/DownUpTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/HorizontalTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/LeftRightAppearTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/LeftRightTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/NoTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/RightLeftAppearTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/RightLeftTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TRANSITIONS.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/Transition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TransitionComposite.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TransitionFactory.java [new file with mode: 0755]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/UpDownAppearTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/UpDownTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/VerticalTransition.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/utils/FileToolbox.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/utils/HTMLStyledTextParser.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/utils/ResourceManager.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/utils/SWTGraphicUtil.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/utils/SimpleSelectionAdapter.java [new file with mode: 0644]
org.tizen.common.externals/src/org/mihalis/opal/utils/StringUtil.java [new file with mode: 0644]
org.tizen.common.externals/src/org/tizen/common/externals/ExternalsPlugin.java [new file with mode: 0644]
org.tizen.common.feature/build.properties
org.tizen.common.feature/feature.xml
org.tizen.common.feature/rootfiles/resources/icons/tizen-sdk-ide.ico [deleted file]
org.tizen.common.verrari/.classpath [new file with mode: 0644]
org.tizen.common.verrari/.project [new file with mode: 0644]
org.tizen.common.verrari/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
org.tizen.common.verrari/META-INF/MANIFEST.MF [new file with mode: 0644]
org.tizen.common.verrari/OSGI-INF/l10n/bundle.properties [new file with mode: 0644]
org.tizen.common.verrari/about.html [new file with mode: 0644]
org.tizen.common.verrari/about_files/LICENSE-2.0.htm [new file with mode: 0644]
org.tizen.common.verrari/about_files/jsoup-LICENSE.txt [new file with mode: 0644]
org.tizen.common.verrari/build.properties [new file with mode: 0644]
org.tizen.common.verrari/lib/jsoup-1.6.3.jar [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/Activator.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/engine/AbstractTemplateEngine.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/engine/ITemplateEngine.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/engine/TemplateEngineFactory.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/engine/freemarker/FreemarkerTemplateEngine.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/engine/jsoup/JsoupTemplateEngine.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/model/IModel.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/model/IModelProvider.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/model/MapModel.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/model/StaticModelProvider.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/target/TargetGroup.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/target/TargetUnit.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/template/FileTemplate.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/template/ITemplate.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/template/ITemplateProvider.java [new file with mode: 0644]
org.tizen.common.verrari/src/org/tizen/common/verrari/template/StaticTemplateProvider.java [new file with mode: 0644]
org.tizen.common.verrari/template/html/description.ftl [new file with mode: 0644]
org.tizen.common.verrari/template/html/index_html.ftl [new file with mode: 0644]
org.tizen.common.verrari/template/html/index_html_body.ftl [new file with mode: 0644]
org.tizen.common.verrari/template/html/test.xml [new file with mode: 0644]
org.tizen.common.verrari/template/js/description.ftl [new file with mode: 0644]
org.tizen.common.verrari/template/js/main_js.ftl [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/TemplateEngineFactoryTest.java [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/FreemarkerTemplateEngineTest.java [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/description.ftl [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/test.html [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/testTizenMulti.html [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/testTizenSingle.html [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/testTizenSingle2.html [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/test_html.ftl [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/test_html_body.ftl [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/jsoup/JsoupTemplateEngineTest.java [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/jsoup/TizenSingle.html [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/jsoup/genTizenSingle.html [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/target/TargetGruopTest.java [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/target/TargetUnitTest.java [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/template/FileTemplateTest.java [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/template/StaticTemplateProviderTest.java [new file with mode: 0644]
org.tizen.common.verrari/test/src/org/tizen/common/verrari/template/test_html.ftl [new file with mode: 0644]
org.tizen.common/.classpath [changed mode: 0644->0755]
org.tizen.common/.settings/org.eclipse.core.resources.prefs [new file with mode: 0644]
org.tizen.common/META-INF/MANIFEST.MF [changed mode: 0644->0755]
org.tizen.common/OSGI-INF/l10n/bundle.properties
org.tizen.common/about.html
org.tizen.common/about_files/freemarker-LICENSE.txt [new file with mode: 0644]
org.tizen.common/build.properties [changed mode: 0644->0755]
org.tizen.common/icons/back.gif [new file with mode: 0644]
org.tizen.common/icons/forward.gif [new file with mode: 0644]
org.tizen.common/lib/commons-collections-3.2.1.jar [new file with mode: 0644]
org.tizen.common/lib/commons-io-2.4.jar [new file with mode: 0644]
org.tizen.common/lib/commons-lang3-3.1.jar [new file with mode: 0644]
org.tizen.common/lib/commons-logging-1.1.1.jar [new file with mode: 0644]
org.tizen.common/lib/commons-pool-1.6.jar [new file with mode: 0644]
org.tizen.common/lib/freemarker.jar [new file with mode: 0644]
org.tizen.common/lib/log4j-1.2.17.jar [new file with mode: 0644]
org.tizen.common/lib/sdblib.jar [new file with mode: 0644]
org.tizen.common/lib/slf4j-api-1.6.4.jar [new file with mode: 0644]
org.tizen.common/lib/slf4j-log4j12-1.6.4.jar [new file with mode: 0644]
org.tizen.common/plugin.xml
org.tizen.common/schema/org.tizen.common.prompter.exsd [new file with mode: 0644]
org.tizen.common/sdblib.jar [deleted file]
org.tizen.common/src/org/tizen/common/Adaptable.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/AppIdGenerator.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/Cabinet.java [new file with mode: 0755]
org.tizen.common/src/org/tizen/common/CommonPlugin.java
org.tizen.common/src/org/tizen/common/Factory.java [moved from org.tizen.common/src/org/tizen/common/model/DefaultTableModel.java with 59% similarity]
org.tizen.common/src/org/tizen/common/FactoryWithArgument.java [moved from org.tizen.common/src/org/tizen/common/control/TableViewContentProvider.java with 55% similarity]
org.tizen.common/src/org/tizen/common/IApplicationConfiguration.java [new file with mode: 0755]
org.tizen.common/src/org/tizen/common/Surrogate.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/SurrogateWithArgument.java [moved from org.tizen.common/src/org/tizen/common/control/TreeViewLabelProvider.java with 58% similarity]
org.tizen.common/src/org/tizen/common/TizenHelpContextIds.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/TizenPlatformConstants.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/TizenProjectType.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/cache/ImageCache.java [deleted file]
org.tizen.common/src/org/tizen/common/control/TableViewCellModifier.java [deleted file]
org.tizen.common/src/org/tizen/common/control/TableViewColumnSorter.java [deleted file]
org.tizen.common/src/org/tizen/common/control/TableViewLabelProvider.java [deleted file]
org.tizen.common/src/org/tizen/common/control/TreeViewContentProvider.java [deleted file]
org.tizen.common/src/org/tizen/common/core/application/InstallPathConfig.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/application/Messages.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/application/Messages.properties [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/application/StatusLineMessageManager.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/application/UpdateManager.java [moved from org.tizen.common/src/org/tizen/common/update/UpdateManager.java with 67% similarity, mode: 0755]
org.tizen.common/src/org/tizen/common/core/command/AbstractCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/Command.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/CommandCancelException.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/CompositeCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/EclipseExecutor.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/ExecutionContext.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/Executor.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/Policy.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/PolicyRegistryFactory.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/Prompter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/file/DirectoryCopyHandlingCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/file/FileHandlingCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/file/WriteFileCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/policy/AbstractMessagePolicy.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/policy/AbstractPolicy.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/policy/FilePolicy.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/policy/MessagePolicy.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/policy/OptionPolicy.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/policy/PolicyRegistry.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/policy/SimplePolicy.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/policy/UncaughtExceptionHandlingPolicy.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/prompter/AbstractOption.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/prompter/AbstractPrompter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/prompter/ChoiceOption.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/prompter/EclipsePrompter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/prompter/GenericOption.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/prompter/NopPrompter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/prompter/Option.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/prompter/RunableOption.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/prompter/SWTPrompter.java [new file with mode: 0755]
org.tizen.common/src/org/tizen/common/core/command/sdb/DevicesSdbCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/sdb/DlogSdbCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/sdb/ForwardSdbCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/sdb/PullSdbCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/sdb/PushSdbCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/sdb/SdbDevicesHandlingCommand.java [moved from org.tizen.common/src/org/tizen/common/model/DefaultTreeModel.java with 62% similarity]
org.tizen.common/src/org/tizen/common/core/command/sdb/SdbHandlingCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/sdb/ShellSdbCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/sdb/SmartDevelopmentBridgeManager.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/core/command/zip/ZipCommand.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/file/AbstractFileHandler.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/file/EclipseFileHandler.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/file/FileHandler.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/file/Filter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/file/PatternFilter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/file/SimpleFileFilter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/file/StandardFileHandler.java [new file with mode: 0755]
org.tizen.common/src/org/tizen/common/file/VirtualFileHandler.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/file/filter/WildCardFilter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/file/filter/WildCardFilterFactory.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/handler/ClearHandler.java [deleted file]
org.tizen.common/src/org/tizen/common/handler/ClipboardHandler.java [deleted file]
org.tizen.common/src/org/tizen/common/handler/CopyHandler.java [deleted file]
org.tizen.common/src/org/tizen/common/handler/Messages.java [deleted file]
org.tizen.common/src/org/tizen/common/handler/OpenFileHandler.java [deleted file]
org.tizen.common/src/org/tizen/common/handler/OpenPreferencesHandler.java [deleted file]
org.tizen.common/src/org/tizen/common/handler/SaveFileHandler.java [deleted file]
org.tizen.common/src/org/tizen/common/handler/messages.properties [deleted file]
org.tizen.common/src/org/tizen/common/manager/StatusLineMessageManager.java [deleted file]
org.tizen.common/src/org/tizen/common/manager/messages.properties [deleted file]
org.tizen.common/src/org/tizen/common/model/AbstractTableModel.java [deleted file]
org.tizen.common/src/org/tizen/common/model/AbstractTableVO.java [deleted file]
org.tizen.common/src/org/tizen/common/model/AbstractTreeModel.java [deleted file]
org.tizen.common/src/org/tizen/common/model/AbstractTreeVO.java [deleted file]
org.tizen.common/src/org/tizen/common/model/ITableModel.java [deleted file]
org.tizen.common/src/org/tizen/common/model/ITreeVO.java [deleted file]
org.tizen.common/src/org/tizen/common/model/IVO.java [deleted file]
org.tizen.common/src/org/tizen/common/preferences/PreferenceMessages.properties [deleted file]
org.tizen.common/src/org/tizen/common/properties/InstallPathConfig.java [deleted file]
org.tizen.common/src/org/tizen/common/queue/Queue.java [deleted file]
org.tizen.common/src/org/tizen/common/ui/CommonColor.java [moved from org.tizen.common/src/org/tizen/common/swt/CommonColor.java with 58% similarity]
org.tizen.common/src/org/tizen/common/ui/TableToolTipListener.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/ui/dialog/ClosableTray.java [moved from org.tizen.common/src/org/tizen/common/swt/ClosableTray.java with 97% similarity]
org.tizen.common/src/org/tizen/common/ui/dialog/PasswordInputDialog.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/ui/page/preference/Messages.java [moved from org.tizen.common/src/org/tizen/common/manager/Messages.java with 68% similarity]
org.tizen.common/src/org/tizen/common/ui/page/preference/Messages.properties [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/ui/page/preference/PreferenceMessages.java [moved from org.tizen.common/src/org/tizen/common/preferences/PreferenceMessages.java with 96% similarity]
org.tizen.common/src/org/tizen/common/ui/page/preference/PreferenceMessages.properties [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/ui/page/preference/TizenBasePreferencePage.java [moved from org.tizen.common/src/org/tizen/common/preferences/TizenBasePreferencePage.java with 83% similarity]
org.tizen.common/src/org/tizen/common/ui/page/wizard/TrayWizardPage.java [moved from org.tizen.common/src/org/tizen/common/swt/TrayWizardPage.java with 97% similarity]
org.tizen.common/src/org/tizen/common/ui/view/console/AnsicodeAdapter.java [moved from org.tizen.common/src/org/tizen/common/console/AnsicodeAdapter.java with 55% similarity, mode: 0755]
org.tizen.common/src/org/tizen/common/ui/view/console/ConsoleManager.java [moved from org.tizen.common/src/org/tizen/common/console/ConsoleManager.java with 98% similarity]
org.tizen.common/src/org/tizen/common/ui/view/console/ConsoleManager2.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/ui/view/console/ConsoleProcessClosure.java [moved from org.tizen.common/src/org/tizen/common/console/ConsoleProcessClosure.java with 90% similarity]
org.tizen.common/src/org/tizen/common/ui/view/console/HyperlinkManager.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/ui/view/console/IConsolePrinter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/ui/view/console/IHyperlinkManager.java [moved from org.tizen.common/src/org/tizen/common/model/ITableVO.java with 62% similarity]
org.tizen.common/src/org/tizen/common/ui/view/console/LinkInfo.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/ui/view/console/MessageConsoleSpy.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/ui/view/console/TextStyle.java [moved from org.tizen.common/src/org/tizen/common/console/TextStyle.java with 96% similarity]
org.tizen.common/src/org/tizen/common/ui/widget/PictureLabel.java [moved from org.tizen.common/src/org/tizen/common/swt/PictureLabel.java with 94% similarity]
org.tizen.common/src/org/tizen/common/update/UpdateMessages.properties [deleted file]
org.tizen.common/src/org/tizen/common/util/ArrayUtil.java [new file with mode: 0755]
org.tizen.common/src/org/tizen/common/util/Assert.java [new file with mode: 0755]
org.tizen.common/src/org/tizen/common/util/BrowserWrapper.java
org.tizen.common/src/org/tizen/common/util/CipherUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/CollectionMap.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/CollectionUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/ControlFileConfig.java
org.tizen.common/src/org/tizen/common/util/DialogUtil.java
org.tizen.common/src/org/tizen/common/util/EFSUtil.java [new file with mode: 0755]
org.tizen.common/src/org/tizen/common/util/FileUtil.java
org.tizen.common/src/org/tizen/common/util/FilenameUtil.java [new file with mode: 0755]
org.tizen.common/src/org/tizen/common/util/FilterIterator.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/FreeMarkerUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/HelpBrowser.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/HostUtil.java [changed mode: 0644->0755]
org.tizen.common/src/org/tizen/common/util/IOUtil.java
org.tizen.common/src/org/tizen/common/util/ImageUtil.java [moved from org.tizen.common/src/org/tizen/common/util/ImageUtils.java with 56% similarity]
org.tizen.common/src/org/tizen/common/util/IteratingAcceptor.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/IteratingAdapter.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/IteratingRunner.java [moved from org.tizen.common/src/org/tizen/common/model/ITreeModel.java with 60% similarity]
org.tizen.common/src/org/tizen/common/util/IteratingUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/LocalPortChecker.java
org.tizen.common/src/org/tizen/common/util/MapUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/NotificationType.java
org.tizen.common/src/org/tizen/common/util/NotifierDialog.java
org.tizen.common/src/org/tizen/common/util/OSChecker.java
org.tizen.common/src/org/tizen/common/util/ObjectUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/ParsingUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/PluginUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/ProjectUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/PropertyUtil.java
org.tizen.common/src/org/tizen/common/util/SWTRunner.java [new file with mode: 0755]
org.tizen.common/src/org/tizen/common/util/SWTUtil.java [changed mode: 0644->0755]
org.tizen.common/src/org/tizen/common/util/SdbCommandUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/StreamGobbler.java [changed mode: 0644->0755]
org.tizen.common/src/org/tizen/common/util/StringUtil.java [changed mode: 0644->0755]
org.tizen.common/src/org/tizen/common/util/ThreadUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/ValidationUtil.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/ViewUtil.java
org.tizen.common/src/org/tizen/common/util/cache/ColorCache.java [moved from org.tizen.common/src/org/tizen/common/cache/ColorCache.java with 63% similarity]
org.tizen.common/src/org/tizen/common/util/cache/FontCache.java [moved from org.tizen.common/src/org/tizen/common/cache/FontCache.java with 83% similarity, mode: 0755]
org.tizen.common/src/org/tizen/common/util/cache/ImageCache.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/cache/NamedColorCache.java [moved from org.tizen.common/src/org/tizen/common/manager/ColorCache.java with 84% similarity]
org.tizen.common/src/org/tizen/common/util/io/Buffer.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/io/BufferInputStream.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/io/BufferOutputStream.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/io/BufferPool.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/log/Logger.java [moved from org.tizen.common/src/org/tizen/common/log/Logger.java with 94% similarity]
org.tizen.common/src/org/tizen/common/util/url/classpath/Connection.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/url/classpath/Handler.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/url/cp/Connection.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/url/cp/Handler.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/url/vf/Connection.java [new file with mode: 0644]
org.tizen.common/src/org/tizen/common/util/url/vf/Handler.java [new file with mode: 0644]
org.tizen.common/test/lib/asm-4.0.jar [new file with mode: 0644]
org.tizen.common/test/lib/asm-tree-4.0.jar [new file with mode: 0644]
org.tizen.common/test/lib/junit-4.10-src.jar [new file with mode: 0644]
org.tizen.common/test/lib/junit-4.10.jar [new file with mode: 0644]
org.tizen.common/test/lib/mockito-all-1.9.0.jar [new file with mode: 0644]
org.tizen.common/test/src/log4j.xml [new file with mode: 0755]
org.tizen.common/test/src/org/tizen/common/AppIdGeneratorTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/ClassSource.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/CommonPluginTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/DirectorySource.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/FrequentlyUsedMatcher.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/JarSource.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/Location.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/TestAgent.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/Transformer.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/UnsafeClassLoader.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/UnsafeRunner.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/application/MessagesTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/application/StatusLineMessageManagerTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/CommandTest.java [new file with mode: 0755]
org.tizen.common/test/src/org/tizen/common/core/command/CompositeCommandTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/ExecutionContextTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/file/FileHandlingCommandTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/policy/PolicyRegistryTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/prompter/GenericOptionTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/prompter/OptionTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/prompter/SWTPrompterTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/sdb/DevicesSdbCommandTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/sdb/DlogSdbCommandTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/sdb/ForwardSdbCommandTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/sdb/PullSdbCommandTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/sdb/PushSdbCommandTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/sdb/ShellSdbCommandTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/core/command/zip/ZipCommandTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/file/SimpleFileFilterTest.java [new file with mode: 0755]
org.tizen.common/test/src/org/tizen/common/file/VirtualFileHandlerTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/file/filter/WildCardFilterFactoryTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/file/filter/WildCardFilterTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/ui/page/preference/MessagesTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/ui/page/wizard/TrayWizardPageTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/ArrayUtilTest.java [new file with mode: 0755]
org.tizen.common/test/src/org/tizen/common/util/AssertTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/CollectionMapTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/CollectionUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/EFSUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/FileUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/FilenameUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/FilterIteratorTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/FreeMarkerUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/HostUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/IOUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/ImageUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/ImageUtilTest.png [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/LocalPortCheckerTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/MapUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/MockRunner.java [moved from org.tizen.common/src/org/tizen/common/control/NotSupportedTypeException.java with 66% similarity]
org.tizen.common/test/src/org/tizen/common/util/ObjectUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/ParsingUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/PluginUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/SWTUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/StringUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/ThreadUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/ValidationUtilTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/io/BufferPoolTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/io/BufferTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/test [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/url/classpath/ConnectionTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/url/classpath/HandlerTest.java [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/url/classpath/a.txt [new file with mode: 0644]
org.tizen.common/test/src/org/tizen/common/util/url/cp/HandlerTest.java [new file with mode: 0644]
package/build.linux
package/pkginfo.manifest

index 3aa5a4c..f3a3e07 100644 (file)
@@ -1,17 +1,18 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: Tizen Common Connection
+Bundle-Name: %Bundle-Name
 Bundle-SymbolicName: org.tizen.common.connection;singleton:=true
 Bundle-Version: 1.0.0.qualifier
 Bundle-Activator: org.tizen.common.connection.ConnectionPlugin
-Bundle-Vendor: Samsung
+Bundle-Vendor: %Bundle-Vendor
 Require-Bundle: org.eclipse.ui,
  org.eclipse.core.runtime,
- org.eclipse.core.resources;bundle-version="3.6.1",
+ org.eclipse.core.resources,
  org.tizen.common
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
-Import-Package: org.tizen.common.util
+Import-Package: org.eclipse.ui.console,
+ org.tizen.common.util
 Bundle-ClassPath: .
 Export-Package: org.tizen.common.connection;
   uses:="org.eclipse.jface.resource,
diff --git a/org.tizen.common.connection/OSGI-INF/l10n/bundle.properties b/org.tizen.common.connection/OSGI-INF/l10n/bundle.properties
new file mode 100644 (file)
index 0000000..30d3796
--- /dev/null
@@ -0,0 +1,27 @@
+Bundle-Name = Tizen Common Connection
+Bundle-Vendor = Samsung Electronics
+
+view.category = Tizen
+view.connectionExplorer = Connection Explorer
+view.log = Log
+
+properties.page.info = Info
+properties.page.permission = Permission
+
+command.category = Connection Explorer
+command.delete.name = Delete
+command.delete.description = Delete a file or folder on the connected target
+command.rename.name = Rename
+command.rename.description = Rename a file or folder on the connected target
+command.refresh.name = Refresh
+command.refresh.description = Referesh contents of the connected target
+command.property.name = Properties
+command.property.description = View properties for a selected file or folder
+
+context.delete.name = Delete
+context.rename.name = Rename
+context.refresh.name = Refresh
+context.properties.name = Properties
+
+extension.name = Connection Resource Drop
+extension-point.name = tools
\ No newline at end of file
index 414cf4b..71c01b3 100644 (file)
@@ -5,6 +5,8 @@ bin.includes = META-INF/,\
                plugin.xml,\
                icons/,\
                about.html,\
-               about_files/
+               about_files/,\
+               OSGI-INF/,\
+               OSGI-INF/l10n/bundle.properties
 jars.compile.order = .,\
                      sdblib.jar
diff --git a/org.tizen.common.connection/icons/Emulator_stop.gif b/org.tizen.common.connection/icons/Emulator_stop.gif
deleted file mode 100644 (file)
index 60cf40c..0000000
Binary files a/org.tizen.common.connection/icons/Emulator_stop.gif and /dev/null differ
diff --git a/org.tizen.common.connection/icons/log/scroll_lock.png b/org.tizen.common.connection/icons/log/scroll_lock.png
new file mode 100644 (file)
index 0000000..41078de
Binary files /dev/null and b/org.tizen.common.connection/icons/log/scroll_lock.png differ
index 89e284e..4a0b771 100644 (file)
@@ -1,25 +1,37 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?eclipse version="3.4"?>
 <plugin>
-   <extension-point id="org.tizen.common.connection.tools" name="tools" schema="schema/tools.exsd"/>
-               <extension
-               point="org.eclipse.ui.views">
-               <category
-                       name="Tizen"
-                       id="org.tizen.nativeapp.viewCategory"/>
+   <extension-point id="org.tizen.common.connection.tools" name="%extension-point.name" schema="schema/tools.exsd"/>
+        <extension
+        point="org.eclipse.ui.views">
+        <category
+            name="%view.category"
+            id="org.tizen.nativeapp.viewCategory"/>
        </extension>
    <extension
          point="org.eclipse.ui.views">
       <view
             category="org.tizen.nativeapp.viewCategory"
             class="org.tizen.common.connection.ui.ConnectionExplorer"
-            icon="icons/Connection Explorer.gif"
+            icon="icons/connection_explorer.gif"
             id="org.tizen.common.connection.ui.ConnectionExplorer"
-            name="Connection Explorer"
+            name="%view.connectionExplorer"
             restorable="true">
       </view>
    </extension>
+
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            name="%view.log"
+            icon="icons/log/logview.gif"
+            category="org.tizen.nativeapp.viewCategory"
+            class="org.tizen.common.connection.ui.LogView"
+            id="org.tizen.common.connection.ui.LogView"
+            allowMultiple = "true">
+      </view>
+   </extension>
+
    <extension
          point="org.eclipse.ui.perspectiveExtensions">
       <perspectiveExtension
          </viewShortcut>
       </perspectiveExtension> 
    </extension>
+      <extension
+         point="org.eclipse.ui.perspectiveExtensions">
+      <perspectiveExtension
+            targetID="org.tizen.nativeapp.perspective">
+         <view
+               id="org.tizen.common.connection.ui.LogView"
+               ratio="1"
+               relationship="stack"
+               relative="org.eclipse.ui.views.TaskList">
+         </view>
+         <viewShortcut
+               id="org.tizen.common.connection.ui.LogView">
+         </viewShortcut>
+      </perspectiveExtension>
+      <perspectiveExtension
+            targetID="org.eclipse.debug.ui.DebugPerspective">
+         <view
+               id="org.tizen.common.connection.ui.LogView"
+               ratio="1"
+               relationship="stack"
+               relative="org.eclipse.ui.views.TaskList">
+         </view>
+         <viewShortcut
+               id="org.tizen.common.connection.ui.LogView">
+         </viewShortcut>
+      </perspectiveExtension>
+   </extension>
    <extension
          id="org.tizen.common.connection.ui.filedrop"
-         name="Connection Resource Drop"
+         name="%extension.name"
          point="org.eclipse.ui.dropActions">
-               <action
-                                                       class="org.tizen.common.connection.sdblib.dnd.FileEntryDropAdapter"
-                                                       id="org.tizen.common.connection.filedrop">
-               </action>
-                                                                               
+         <action
+         class="org.tizen.common.connection.sdblib.dnd.FileEntryDropAdapter"
+         id="org.tizen.common.connection.filedrop">
+         </action>
    </extension>
    <extension
          point="org.eclipse.ui.propertyPages">
       <page
             class="org.tizen.common.connection.properties.ConnectionExplorerInfoPropertyPages"
             id="org.tizen.common.connection.properties.Info"
-            name="Info"
+            name="%properties.page.info"
             nameFilter="*"
             objectClass="org.tizen.sdblib.FileListingService$FileEntry">
       </page>
          <page
                class="org.tizen.common.connection.properties.ConnectionExplorerPermissionPropertyPages"
                id="org.tizen.common.connection.properties.Permission"
-               name="Permission"
+               name="%properties.page.permission"
                nameFilter="*"
                objectClass="org.tizen.sdblib.FileListingService$FileEntry">
       </page>
    </extension>
    <extension
          point="org.eclipse.ui.commands">
+      <category
+            id="org.tizen.common.connection.category"
+            name="%command.category">
+      </category>
       <command
+            categoryId="org.tizen.common.connection.category"
+            description="%command.delete.description"
             id="org.tizen.common.connection.delete"
-            name="deleteaction">
+            name="%command.delete.name">
       </command>
       <command
+            categoryId="org.tizen.common.connection.category"
+            description="%command.rename.description"
             id="org.tizen.common.connection.rename"
-            name="renameaction">
+            name="%command.rename.name">
       </command>
       <command
+            categoryId="org.tizen.common.connection.category"
+            description="%command.refresh.description"
             id="org.tizen.common.connection.refresh"
-            name="refreshaction">
+            name="%command.refresh.name">
       </command>
       <command
+            categoryId="org.tizen.common.connection.category"
+            description="%command.property.description"
             id="org.tizen.common.connection.property"
-            name="propertyaction">
+            name="%command.property.name">
       </command>
    </extension>
    <extension
          point="org.eclipse.ui.contexts">
       <context
             id="org.tizen.common.connection.delete.context"
-            name="delete"
+            name="%context.delete.name"
             parentId="org.eclipse.ui.contexts.window">
       </context>
       <context
             id="org.tizen.common.connection.rename.context"
-            name="rename"
+            name="%context.rename.name"
             parentId="org.eclipse.ui.contexts.window">
       </context>
       <context
             id="org.tizen.common.connection.refresh.context"
-            name="refresh"
+            name="%context.refresh.name"
             parentId="org.eclipse.ui.contexts.window">
       </context>
       <context
             id="org.tizen.common.connection.property.context"
-            name="property"
+            name="%context.properties.name"
             parentId="org.eclipse.ui.contexts.window">
       </context>
    </extension>
-   
-       <extension
-         point="org.eclipse.ui.views">
-      <view
-            name="Log"
-            icon="icons/log/Log View.gif"
-            category="org.tizen.nativeapp.viewCategory"
-            class="org.tizen.common.connection.ui.LogView"
-            id="org.tizen.common.connection.ui.LogView"
-            allowMultiple = "true">
-      </view>
-   </extension>
-   
-      <extension
-         point="org.eclipse.ui.perspectiveExtensions">
-      <perspectiveExtension
-            targetID="org.tizen.nativeapp.perspective">      
-         <view
-               id="org.tizen.common.connection.ui.LogView"
-               ratio="1"
-               relationship="stack"
-               relative="org.eclipse.ui.views.TaskList">
-         </view>
-         <viewShortcut
-               id="org.tizen.common.connection.ui.LogView">
-         </viewShortcut>
-      </perspectiveExtension> 
-   </extension>   
    </plugin>
old mode 100644 (file)
new mode 100755 (executable)
index dc5cbf6..09d28fd
@@ -1,36 +1,36 @@
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* Hoon Kang <h245.kang@samsung.com>
-* Hyunsik Noh <hyunsik.noh@samsung.com>
-* 
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Hoon Kang <h245.kang@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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
-*
-*/ 
+ * 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.common.connection;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Properties;
 
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtensionRegistry;
@@ -40,11 +40,13 @@ import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
 import org.tizen.common.connection.debugtools.DebugTool;
-import org.tizen.common.properties.InstallPathConfig;
-
+import org.tizen.common.core.application.InstallPathConfig;
+import org.tizen.common.util.FileUtil;
+import org.tizen.common.util.HostUtil;
+import org.tizen.common.util.OSChecker;
+import org.tizen.common.util.log.Logger;
 import org.tizen.sdblib.FileListingService.FileEntry;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.Log;
 import org.tizen.sdblib.SmartDevelopmentBridge;
 
 /**
@@ -52,23 +54,23 @@ import org.tizen.sdblib.SmartDevelopmentBridge;
  */
 public class ConnectionPlugin extends AbstractUIPlugin {
 
-       // The plug-in ID
-       public static final String PLUGIN_ID = "org.tizen.common.connection"; //$NON-NLS-1$
-       public static final String ID_LOGS_VIEW = "org.tizen.common.connection.ui.LogView"; //$NON-NLS-1$
-       public static final String ID_CONNECTION_VIEW = "org.tizen.common.connection.ui.ConnectionExplorer";
-       public static final String ID_DEBUGTOOLS_EXTENSION = "org.tizen.common.connection.tools"; //$NON-NLS-1$
-       
-       // The shared instance
-       private static ConnectionPlugin plugin;
-       
-       private IDevice currentDevice;
-       private final ArrayList<ISelectionListener> listeners = new ArrayList<ISelectionListener>();
-       
-       public int os;
-       public static final int LINUX = 0;
-       public static final int WINDOWS = 1;
-       
-        /**
+    // The plug-in ID
+    public static final String PLUGIN_ID = "org.tizen.common.connection"; //$NON-NLS-1$
+    public static final String ID_LOGS_VIEW = "org.tizen.common.connection.ui.LogView"; //$NON-NLS-1$
+    public static final String ID_CONNECTION_VIEW = "org.tizen.common.connection.ui.ConnectionExplorer";
+    public static final String ID_DEBUGTOOLS_EXTENSION = "org.tizen.common.connection.tools"; //$NON-NLS-1$
+
+    // The shared instance
+    private static ConnectionPlugin plugin;
+
+    private IDevice currentDevice;
+    private final ArrayList<ISelectionListener> listeners = new ArrayList<ISelectionListener>();
+
+    public int os;
+    public static final int LINUX = 0;
+    public static final int WINDOWS = 1;
+
+    /**
      * Implements for FileEntry changed status.
      */
     public interface ISelectionListener {
@@ -79,143 +81,210 @@ public class ConnectionPlugin extends AbstractUIPlugin {
          */
         void selectionChanged(FileEntry selectedEntry);
     }
-    
-       /**
-        * The constructor
-        */
-       public ConnectionPlugin() {
-       }
-
-       /*
-        * (non-Javadoc)
-        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
-        */
-       public void start(BundleContext context) throws Exception {
-       
-               super.start(context);
-               plugin = this;
-               
-               Properties properties = System.getProperties();
-               String value = properties.getProperty("os.name");
-               if (value.contains("Windows"))
-                       this.os = WINDOWS;
-               else
-                       this.os = LINUX;        
-               
-       }
-       
-       public static synchronized  List<DebugTool> getDebugTools(IDevice device) {
-       
-               List<DebugTool> toolLists = new ArrayList<DebugTool>();
-               
-               IExtensionRegistry x = RegistryFactory.getRegistry();
-               IConfigurationElement[] ces = x.getConfigurationElementsFor(ID_DEBUGTOOLS_EXTENSION);
-               
-               for (int i = 0; i < ces.length; ++i) {
-                       IConfigurationElement ce = ces[i];
-                       if (ce.getName().equals("tools")) { 
-                               String packagename = ce.getAttribute("packagename"); 
-                               if (packagename == null) 
-                                       continue;
-                               String sourcepath = ce.getAttribute("sourcepath");
-                               if (sourcepath == null) 
-                                       continue;
-                               String description = ce.getAttribute("description"); 
-                               
-                               Path sourcePath = new Path(InstallPathConfig.getSDKPath() + "/" + sourcepath);
-                               
-                               File packageList = new File(sourcePath.toOSString());
-                               for (File f : packageList.listFiles()) {
-                                       if (f.getName().startsWith(packagename)) {
-                                               String[] filename = f.getName().split("_");
-                                               if (filename.length != 3)
-                                                       continue;
-                                               String version = filename[1];           
-                                               String[] arch = filename[2].split("\\.");
-                                               if (arch.length != 2)
-                                                       continue;
-                                               String architecture = arch[0];  
-                                               
-                                               if (device.isEmulator()) {
-                                                       if (!architecture.equals("i386"))
-                                                               continue;
-                                               } else {
-                                                       if (!architecture.equals("armel"))
-                                                               continue;
-                                               }                                               
-                                               DebugTool dt = new DebugTool();
-                                               dt.setPackagename(packagename);
-                                               dt.setBinaryname(f.getName());
-                                               dt.setSourcepath(sourcepath);
-                                               dt.setDescription(description);
-                                               dt.setVersion(version);
-                                               dt.setArchitecture(architecture);
-                                               toolLists.add(dt);
-                                       }
-                               }
-                       }
-               }
-               return toolLists;
-       }
-       
-       /*
-        * (non-Javadoc)
-        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
-        */
-       public void stop(BundleContext context) throws Exception {
-               plugin = null;
-               SmartDevelopmentBridge.disconnectBridge();
-               super.stop(context);
-       }
-
-       /**
-        * Returns the shared instance
-        *
-        * @return the shared instance
-        */
-       public static ConnectionPlugin getDefault() {
-               return plugin;
-       }
-       
-       public void setCurrentDevice(IDevice device)    {
-               currentDevice = device; 
-       }
-       
-       public IDevice getCurrentDevice()       {
-               return currentDevice;
-       }
-       
-       
-       public void addSelectionListener(ISelectionListener listener) {
-               listeners.add(listener);
-       }
-
-       public void removeSelectionListener(ISelectionListener listener) {
-               listeners.remove(listener);
-       }
-       
-       public void notifySelectionListeners(FileEntry file) {
-               
-               ISelectionListener[] listenersCopy = listeners.toArray(
-                               new ISelectionListener[listeners.size()]);
-               
-               for (ISelectionListener listener : listenersCopy)       {
-                       try {
-                               listener.selectionChanged(file);                        
-                       } catch (Exception e) {
-                               Log.e("ConnectionPlugin", e);
-                       }
-              }
-       }
-       
-       /**
-        * Returns an image descriptor for the image file at the given
-        * plug-in relative path
-        *
-        * @param path the path
-        * @return the image descriptor
-        */
-       public static ImageDescriptor getImageDescriptorFromPlugin(String path) {
-               return imageDescriptorFromPlugin(PLUGIN_ID, path);
-       }
+
+    /**
+     * The constructor
+     */
+    public ConnectionPlugin() {
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    public void start(BundleContext context) throws Exception {
+
+        super.start(context);
+        plugin = this;
+
+        if (OSChecker.isWindows())
+        {
+            this.os = WINDOWS;
+        }
+        else
+        {
+            this.os = LINUX;
+        }
+
+    }
+
+    public static synchronized  List<DebugTool> getDebugTools(IDevice device) {
+        List<DebugTool> toolLists = new ArrayList<DebugTool>();
+        IExtensionRegistry x = RegistryFactory.getRegistry();
+        IConfigurationElement[] ces = x.getConfigurationElementsFor(ID_DEBUGTOOLS_EXTENSION);
+
+        try {
+            for ( IConfigurationElement ce : ces ) {
+                if (ce.getName().equals("tools")) {
+                    String packagename = ce.getAttribute("packagename");
+                    if (packagename == null)
+                    {
+                        continue;
+                    }
+                    String sourcepath = ce.getAttribute("sourcepath");
+                    if (sourcepath == null)
+                    {
+                        continue;
+                    }
+                    String description = ce.getAttribute("description");
+                    Path sourcePath = new Path(InstallPathConfig.getPlatformVersionPath() + "/" + sourcepath);
+                    File packageList = new File(sourcePath.toOSString());
+                    
+                    DebugTool dt = null;
+                    File[] packageFileList = packageList.listFiles();
+                    if ( packageFileList == null ) {
+                        continue;
+                    }
+                    for (File f : packageList.listFiles()) {
+                        if ( DebugTool.RPM_PACKAGE_TYPE.equals(FileUtil.getFileExtension(f.getName())) ) {
+                            dt = makeDebugToolFromRPM(f, device, packagename, sourcepath, description);
+                        }
+                        else {
+                            dt = makeDebugToolFromTar(f, device, packagename, sourcepath, description);
+                        }
+                        if ( dt != null ) {
+                            toolLists.add(dt);
+                        }
+                    }
+                }
+            }
+        } catch (Throwable e) {
+            Logger.error("Failed making DebugTool list for on-demand install", e);
+        }
+        return toolLists;
+    }
+
+    private static DebugTool makeDebugToolFromRPM( File f, IDevice device, String packagename, String sourcepath, String description ) {
+        String architecture = "";
+        String version = "";
+        String name = "";
+
+        // Not supported "RPM" at windows
+        //            architecture = HostUtil.returnExecute( String.format( DebugTool.RPM_QUERY_COMMAND, "%{ARCH}", "-p " + f.getCanonicalPath()) );
+        //            version = HostUtil.returnExecute( String.format( DebugTool.RPM_QUERY_COMMAND, "%{VERSION}", "-p " + f.getCanonicalPath()) );
+        //            name = HostUtil.returnExecute( String.format( DebugTool.RPM_QUERY_COMMAND, "%{NAME}", "-p " + f.getCanonicalPath()) );
+
+        // RPM file format : gtest-0.0.8-7.1.armv7l.rpm
+        String[] fileSplit = f.getName().split("-");
+        if ( fileSplit.length < 3 ) {
+            return null;
+        }
+        name = fileSplit[0];
+        // version is not used
+        // FIXME : Unsafe way to extract the version.
+        version = fileSplit[1];
+        String[] archSplit = fileSplit[fileSplit.length-1].split("\\.");
+        architecture = archSplit[archSplit.length-2];
+        
+        if ( !packagename.equals(name) ) {
+            return null;
+        }
+        if (device.isEmulator()) {
+            if ( !architecture.contains("86")) {
+                return null;
+            }
+        }
+        else {
+            if ( !architecture.contains("arm")) {
+                return null;
+            }
+        }
+
+        DebugTool dt = new DebugTool(packagename, f.getName(), sourcepath, version, description, architecture, DebugTool.RPM_PACKAGE_TYPE);
+
+        return dt;
+    }
+
+    private static DebugTool makeDebugToolFromTar( File f, IDevice device, String packagename, String sourcepath, String description ) {
+        String[] filename = f.getName().split("_");
+        if (filename.length != 3) {
+            return null;
+        }
+        if( !filename[0].equals(packagename)) {
+            return null;
+        }
+        String version = filename[1];
+        String[] arch = filename[2].split("\\.");
+        if (arch.length != 2) {
+            return null;
+        }
+        String architecture = arch[0];
+
+        if (device.isEmulator()) {
+            if (!architecture.equals("i386"))
+            {
+                return null;
+            }
+        } else {
+            if (!architecture.equals("armel"))
+            {
+                return null;
+            }
+        }
+
+        DebugTool dt = new DebugTool(packagename, f.getName(), sourcepath, version, description, architecture, "tar");
+        return dt;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext context) throws Exception {
+        plugin = null;
+        int deviceCnt = SmartDevelopmentBridge.getBridge().getDevices().length;
+        if (deviceCnt==0)
+            SmartDevelopmentBridge.disconnectBridge();
+        super.stop(context);
+    }
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static ConnectionPlugin getDefault() {
+        return plugin;
+    }
+
+    public void setCurrentDevice(IDevice device) {
+        currentDevice = device;
+    }
+
+    public IDevice getCurrentDevice() {
+        return currentDevice;
+    }
+
+    public void addSelectionListener(ISelectionListener listener) {
+        listeners.add(listener);
+    }
+
+    public void removeSelectionListener(ISelectionListener listener) {
+        listeners.remove(listener);
+    }
+
+    public void notifySelectionListeners(FileEntry file) {
+
+        ISelectionListener[] listenersCopy = listeners.toArray(
+                new ISelectionListener[listeners.size()]);
+
+        for (ISelectionListener listener : listenersCopy) {
+            try {
+                listener.selectionChanged(file);
+            } catch (Exception e) {
+                Logger.error("ConnectionPlugin", e);
+            }
+        }
+    }
+
+    /**
+     * Returns an image descriptor for the image file at the given
+     * plug-in relative path
+     *
+     * @param path the path
+     * @return the image descriptor
+     */
+    public static ImageDescriptor getImageDescriptorFromPlugin(String path) {
+        return imageDescriptorFromPlugin(PLUGIN_ID, path);
+    }
 }
\ No newline at end of file
diff --git a/org.tizen.common.connection/src/org/tizen/common/connection/ConnectionPluginSurrogate.java b/org.tizen.common.connection/src/org/tizen/common/connection/ConnectionPluginSurrogate.java
new file mode 100644 (file)
index 0000000..5cc6a6c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Kangho Kim <kh5325.kim@samsung.com>
+* Hyeongseok Heo <hyeongseok.heo@samsung.com>
+* BonYong Lee <bonyong.lee@samsung.com>
+* Gyeongseok Seo <gyeongseok.seo@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.common.connection;
+
+import org.tizen.common.Surrogate;
+
+/**
+ * The ConnectionPluginSurrogate class adapt ConnectionPlugin default object
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * @author Gyeongseok Seo <gyeongseok.seo@samsung.com>
+ */
+public class ConnectionPluginSurrogate implements Surrogate<ConnectionPlugin> {
+    @Override
+    public ConnectionPlugin getAdapter() {
+        return ConnectionPlugin.getDefault();
+    }
+}
index 9d22035..a6af7cb 100644 (file)
@@ -1,30 +1,32 @@
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* Hoon Kang <h245.kang@samsung.com>
-* Yoonki Park <yoonki.park@samsung.com>
-* 
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hoon Kang <h245.kang@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
-*
-*/
+ * 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.common.connection.ddmuilib;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.osgi.util.NLS;
@@ -32,147 +34,73 @@ import org.eclipse.swt.SWT;
 import org.eclipse.ui.PlatformUI;
 import org.tizen.common.connection.explorer.Messages;
 
+public class FileDialogUtils
+{
+    public static int checkOverwrite(final String filename)
+    {
+        String message = NLS.bind(Messages.getString("FileDialogUtils.overwrite.message"), filename);
+        String[] labels = new String[] { IDialogConstants.YES_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL,
+                IDialogConstants.CANCEL_LABEL };
+        int type = MessageDialog.QUESTION;
+        return openFileDialog(labels, message, type);
+    }
 
-public class FileDialogUtils {
-       private static FileDialogUtils instance;
-       
-       private FileDialogUtils() { }
-       
-       public static FileDialogUtils getInstance() {
-               if (instance == null)
-                       instance = new FileDialogUtils();
-               return instance;
-       }
-       
-       public int checkOverwrite(final String filename) {
-               final int[] result = new int[1]; // using array since you can't change a final int
-
-               Runnable query = new Runnable() {
-                       public void run() {
-                               int[] resultId = {
-                                               IDialogConstants.YES_ID,
-                                               IDialogConstants.YES_TO_ALL_ID,
-                                               IDialogConstants.NO_ID,
-                                               IDialogConstants.CANCEL_ID };
-
-                               String[] labels = new String[] {
-                                               IDialogConstants.YES_LABEL,
-                                               IDialogConstants.YES_TO_ALL_LABEL,
-                                               IDialogConstants.NO_LABEL,
-                                               IDialogConstants.CANCEL_LABEL };
-                               
-                               String msg = NLS.bind(Messages.getString("FileDialogUtils.overrite.message"), filename);
-                               MessageDialog dialog = new MessageDialog(
-                                               PlatformUI.getWorkbench().getDisplay().getActiveShell(),
-                                               Messages.getString("FileDialogUtils.overrite.title"),
-                                               null, msg , MessageDialog.QUESTION, labels, 0);
-                               dialog.open();
-                               if (dialog.getReturnCode() == SWT.DEFAULT) {
-                                       // A window close returns SWT.DEFAULT - mapped to a cancel
-                                       result[0] = IDialogConstants.CANCEL_ID;
-                               } else {
-                                       result[0] = resultId[dialog.getReturnCode()];
-                               }
-                       }
-               };
-
-               PlatformUI.getWorkbench().getDisplay().syncExec(query);
-               return result[0];
-       }
-       public int confirmDelete(final String filename) {
-               final int[] result = new int[1]; // using array since you can't change a final int
-
-               Runnable query = new Runnable() {
-                       public void run() {
-                               int[] resultId = {
-                                               IDialogConstants.YES_ID,
-                                               IDialogConstants.CANCEL_ID };
-
-                               String[] labels = new String[] {
-                                               IDialogConstants.YES_LABEL,
-                                               IDialogConstants.CANCEL_LABEL };
-                               
-                               String msg = NLS.bind(Messages.getString("FileDialogUtils.delete.message"), filename);
-                               MessageDialog dialog = new MessageDialog(
-                                               PlatformUI.getWorkbench().getDisplay().getActiveShell(),
-                                               Messages.getString("FileDialogUtils.delete.title"),
-                                               null, msg , MessageDialog.QUESTION, labels, 0);
-                               dialog.open();
-                               if (dialog.getReturnCode() == SWT.DEFAULT) {
-                                       // A window close returns SWT.DEFAULT - mapped to a cancel
-                                       result[0] = IDialogConstants.CANCEL_ID;
-                               } else {
-                                       result[0] = resultId[dialog.getReturnCode()];
-                               }
-                       }
-               };
-
-               PlatformUI.getWorkbench().getDisplay().syncExec(query);
-               return result[0];
-       }
-       
-       public int checkFileOverwrite(final String filename) {
-               final int[] result = new int[1]; // using array since you can't change a final int
-
-               Runnable query = new Runnable() {
-                       public void run() {
-                               int[] resultId = {
-                                               IDialogConstants.OK_ID,
-                                               IDialogConstants.CANCEL_ID };
+    public static int confirmDelete(final String filename)
+    {
+        String message = NLS.bind(Messages.getString("FileDialogUtils.delete.message"), filename);
+        String[] labels = new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL };
+        int type = MessageDialog.QUESTION;
+        return openFileDialog(labels, message, type);
+    }
 
-                               String[] labels = new String[] {
-                                               IDialogConstants.OK_LABEL,
-                                               IDialogConstants.CANCEL_LABEL };
-                               
-                               String msg = NLS.bind(Messages.getString("FileDialogUtils.overrite.message"), filename);
-                               MessageDialog dialog = new MessageDialog(
-                                               PlatformUI.getWorkbench().getDisplay().getActiveShell(),
-                                               Messages.getString("FileDialogUtils.overrite.title"),
-                                               null, msg , MessageDialog.QUESTION, labels, 0);
-                               dialog.open();
-                               if (dialog.getReturnCode() == SWT.DEFAULT) {
-                                       // A window close returns SWT.DEFAULT - mapped to a cancel
-                                       result[0] = IDialogConstants.CANCEL_ID;
-                               } else {
-                                       result[0] = resultId[dialog.getReturnCode()];
-                               }
-                       }
-               };
+    public static int allowFileOverwrite(final String filename)
+    {
+        String message = NLS.bind(Messages.getString("FileDialogUtils.overwrite.message"), filename);
+        String[] labels = new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL };
+        int type = MessageDialog.QUESTION;
+        return openFileDialog(labels, message, type);
+    }
 
-               PlatformUI.getWorkbench().getDisplay().syncExec(query);
-               return result[0];
-       }
-       
-       public int checkTabName(final String filename) {
-               final int[] result = new int[1]; // using array since you can't change a final int
+    public static int checkTabName(final String filename)
+    {
+        String message = NLS.bind(Messages.getString("FileDialogUtils.tabName.message"), filename);
+        String[] labels = new String[] { IDialogConstants.OK_LABEL };
+        int type = MessageDialog.ERROR;
+        return openFileDialog(labels, message, type);
+    }
 
-               Runnable query = new Runnable() {
-                       public void run() {
-                               int[] resultId = {
-                                               IDialogConstants.OK_ID
-                                               };
+    public static void notifyDuplication(final String filename)
+    {
+        String message = NLS.bind(Messages.getString("FileDialogUtils.duplicate.message"), filename);
+        String[] labels = new String[] { IDialogConstants.OK_LABEL };
+        int type = MessageDialog.ERROR;
+        openFileDialog(labels, message, type);
+    }
 
-                               String[] labels = new String[] {
-                                               IDialogConstants.OK_LABEL
-                                                };
-                               
-                               String msg = NLS.bind(Messages.getString("FileDialogUtils.tabName.message"), filename);
-                               MessageDialog dialog = new MessageDialog(
-                                               PlatformUI.getWorkbench().getDisplay().getActiveShell(),
-                                               Messages.getString("FileDialogUtils.tabName.title"),
-                                               null, msg , MessageDialog.ERROR, labels, 0);
-                               dialog.open();
-                               if (dialog.getReturnCode() == SWT.DEFAULT) {
-                                       // A window close returns SWT.DEFAULT - mapped to a cancel
-                                       result[0] = IDialogConstants.CANCEL_ID;
-                               } else {
-                                       result[0] = resultId[dialog.getReturnCode()];
-                               }
-                       }
-               };
+    private static int openFileDialog(final String[] labels, final String message, final int type)
+    {
+        final AtomicInteger resultAtomicInteger = new AtomicInteger();
+        Runnable query = new Runnable()
+        {
+            @Override
+            public void run()
+            {
+                String title = Messages.getString("FileDialogUtils.message.title");
+                MessageDialog dialog = new MessageDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(),
+                        title, null, message, type, labels, 0);
+                dialog.open();
+                if (dialog.getReturnCode() == SWT.DEFAULT)
+                {
+                    // A window close returns SWT.DEFAULT - mapped to a cancel
+                    resultAtomicInteger.set(IDialogConstants.CANCEL_ID);
+                } else
+                {
+                    resultAtomicInteger.set(dialog.getReturnCode());
+                }
+            }
+        };
 
-               PlatformUI.getWorkbench().getDisplay().syncExec(query);
-               return result[0];
-       }
-       
-}
+        PlatformUI.getWorkbench().getDisplay().syncExec(query);
+        return resultAtomicInteger.get();
+    }
+}
\ No newline at end of file
index 6ed16fd..24e52f9 100644 (file)
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* Hoon Kang <h245.kang@samsung.com>
-* YoonKi Park <yoonki.park@samsung.com>
-* 
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Hoon Kang <h245.kang@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
-*
-*/
+ * 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.common.connection.debugtools;
 
-import org.tizen.common.properties.InstallPathConfig;
+import org.tizen.common.TizenPlatformConstants;
+import org.tizen.common.core.application.InstallPathConfig;
 
 public class DebugTool {
-       public static final String CONTROL_EXTENSION = ".control";
-       public static final String TOOLS_TARGET_PATH = "/home/developer/sdk_tools";
-       public static final String TOOLS_HOST_PATH = InstallPathConfig.getSDKPath();
-       
-       private String binaryname; 
-       private String packagename;
-       private String sourcepath; 
-       private String architecture; 
-       private String description;
-       private String version;
-       
-       public DebugTool() { 
-               
-       }
-       public String getBinaryname() {
-               return binaryname;
-       }
-       public String getControlFile() { 
-               return "." + this.packagename + CONTROL_EXTENSION;
-       }
-       public String getVersion() {
-               return version;
-       }
-       public void setVersion(String pVersion) { 
-               version = pVersion;
-       }
-       public void setBinaryname(String pBinaryname) {
-               binaryname = pBinaryname;
-       }
-       public String getPackagename() {
-               return packagename;
-       }
-       public void setPackagename(String pPackagename) {
-                packagename = pPackagename;
-       }
-       public String getSourcepath() {
-               return sourcepath;
-       }
-       public void setSourcepath(String pSourcepath) {
-               sourcepath = pSourcepath;
-       }
-       public String getArchitecture() {
-               return architecture;
-       }
-       public void setArchitecture(String pArchitecture) {
-               architecture = pArchitecture;
-       }
-       public String getDescription() {
-               return description;
-       }
-       public void setDescription(String pDescription) {
-               description = pDescription;
-       }
-       
+    public static final String TOOLS_HOST_PATH = InstallPathConfig.getPlatformVersionPath();
+    public static final String RPM_QUERY_COMMAND = "rpm -q --queryformat=%s %s";
+    public static final String RPM_PACKAGE_TYPE = "rpm";
+    public static final String RPM_INSTALL_COMMAND = "rpm -i %s";
+    public static final String RPM_UPGRADE_COMMAND = "rpm -U %s";
+
+    private String binaryname;
+    private String packagename;
+    private String sourcepath;
+    private String architecture;
+    private String description;
+    private String version;
+    private String packagetype;
+
+    public DebugTool() {
+
+    }
+    public DebugTool(String packagename, String binaryname, String sourcepath, String version, String desc, String arch, String type) {
+        this.packagename = packagename;
+        this.binaryname = binaryname;
+        this.sourcepath = sourcepath;
+        this.version = version;
+        this.description = desc;
+        this.architecture = arch;
+        this.packagetype = type;
+    }
+    public String getBinaryname() {
+        return binaryname;
+    }
+    public String getControlFile() {
+        return "." + this.packagename + TizenPlatformConstants.CONTROL_EXTENSION;
+    }
+    public String getVersion() {
+        return version;
+    }
+    public void setVersion(String pVersion) {
+        version = pVersion;
+    }
+    public void setBinaryname(String pBinaryname) {
+        binaryname = pBinaryname;
+    }
+    public String getPackagename() {
+        return packagename;
+    }
+    public void setPackagename(String pPackagename) {
+        packagename = pPackagename;
+    }
+    public String getSourcepath() {
+        return sourcepath;
+    }
+    public void setSourcepath(String pSourcepath) {
+        sourcepath = pSourcepath;
+    }
+    public String getArchitecture() {
+        return architecture;
+    }
+    public void setArchitecture(String pArchitecture) {
+        architecture = pArchitecture;
+    }
+    public String getDescription() {
+        return description;
+    }
+    public void setDescription(String pDescription) {
+        description = pDescription;
+    }
+    public void setPackagetype(String packagetype) {
+        this.packagetype = packagetype;
+    }
+    public String getPackagetype() {
+        return packagetype;
+    }
+
 }
old mode 100644 (file)
new mode 100755 (executable)
index c628278..75f7af0
@@ -1,35 +1,40 @@
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* Hoon Kang <h245.kang@samsung.com>
-* YoonKi Park <yoonki.park@samsung.com>
-* 
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Hoon Kang <h245.kang@samsung.com>
+ * YoonKi Park <yoonki.park@samsung.com>
+ * Gun Kim <gune.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
-*
-*/
+ * 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.common.connection.debugtools;
 
+import static org.tizen.common.util.CollectionUtil.isEmpty;
+import static org.tizen.common.util.IOUtil.tryClose;
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Pattern;
 
@@ -41,284 +46,335 @@ import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
+import org.tizen.common.TizenPlatformConstants;
 import org.tizen.common.connection.ConnectionPlugin;
-import org.tizen.common.log.Logger;
-
+import org.tizen.common.util.IOUtil;
+import org.tizen.common.util.SdbCommandUtil;
+import org.tizen.common.util.log.Logger;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.SdbCommandRejectedException;
 import org.tizen.sdblib.SdbShellProcess;
-import org.tizen.sdblib.SyncService;
-import org.tizen.sdblib.SyncService.SyncResult;
-import org.tizen.sdblib.TimeoutException;
 
 class PackageInstallMonitorDialog extends ProgressMonitorDialog {
-       public PackageInstallMonitorDialog(Shell parent) {
-               super(parent);
-               int shellStyle = getShellStyle();
-               shellStyle &= ~SWT.APPLICATION_MODAL;
-               setShellStyle(shellStyle);
-       }
+    public PackageInstallMonitorDialog(Shell parent) {
+        super(parent);
+        int shellStyle = getShellStyle();
+        shellStyle &= ~SWT.APPLICATION_MODAL;
+        setShellStyle(shellStyle);
+    }
 }
 
 class InstallProgress implements IRunnableWithProgress {
 
-       private static final String CMD_RESULT_CHECK = "; echo $?";
-
-       private IDevice device = null;
-
-       IProgressMonitor monitor = null;
-
-       private boolean checkDirectory(String dir) throws CoreException {
-               String cmd = "ls " + dir + CMD_RESULT_CHECK;
-               return checkExitCode(cmd, ToolsInstallMessages.CANNOT_CHECK_DIRECTORY);         
-       }
-       
-
-       private void makeDirectory(String dir) throws CoreException {
-               String cmd = "mkdir -p -m 755 " + dir + CMD_RESULT_CHECK ;
-               String msg = ToolsInstallMessages.CANNOT_CREATE_DIRECTORY;
-               
-               if (checkExitCode(cmd, msg) == false)
-                       installCoreException(msg, null);                        
-       }
-       
-       private boolean checkExitCode( String cmd, String msg ) throws CoreException
-       {
-               boolean result = false;
-               SdbShellProcess lsProc;
-               BufferedReader br = null;
-               try {
-                       lsProc = device.executeShellCommand(cmd);
-                       br = new BufferedReader(new InputStreamReader(
-                                       lsProc.getInputStream()));
-                       String lsOut = null;
-                       while (null != (lsOut = br.readLine())) {
-                               if ("0".equals(lsOut)) {
-                                       result = true;
-                                       break;
-                                       }
-                       }
-               } catch (IOException e) {
-                       installCoreException(msg, e);
-                       Logger.error(msg, e);
-               }finally
-               {
-                       if( br != null )
-                               try {
-                                       br.close();
-                               } catch (IOException e) {
-                                       Logger.error("Error to close BufferedReader", e);
-                               }
-               }
-               return result;
-       }
-
-       private boolean isInstalled(DebugTool dt) throws CoreException {
-               boolean ret = false;
-               BufferedReader br = null;
-               try {
-                       
-                       SdbShellProcess echoProc = device.executeShellCommand(
-                                       "cat " + DebugTool.TOOLS_TARGET_PATH + "/" + dt.getControlFile() + CMD_RESULT_CHECK);
-                       br = new BufferedReader(new InputStreamReader(
-                                       echoProc.getInputStream()));
-                       
-                       String lsOut = null;
-                       String oldVersion = null;
-                       while (null != (lsOut = br.readLine())) {
-                               //version:0.0.0                         
-                               if (lsOut.toLowerCase().startsWith("version:")) {
-                                       oldVersion = lsOut.split(":")[1];
-                               }                                       
-                       
-                               if ("0".equals(lsOut)) {
-                                       String v1 = normalisedVersion(oldVersion, ".", 4);
-                                       String v2 = normalisedVersion(dt.getVersion(), ".", 4);
-                                       if (v2.compareTo(v1) > 0) { 
-                                               //TODO : do install and save!
-                                               ret = false;
-                                       } else { //same version
-                                               ret = true;
-                                       }
-                                       break;
-                               } else 
-                                       ret = false;            
-                       }
-               } catch (IOException e) {
-                       installCoreException(ToolsInstallMessages.CANNOT_CHECK_INSTALLED, e);
-                       Logger.error(ToolsInstallMessages.CANNOT_CHECK_INSTALLED, e);
-               } finally {
-                       if(br != null)
-                               try {
-                                       br.close();
-                               } catch (IOException e) {
-                                       Logger.error("Error to close BufferedReader", e);
-                               }
-               }
-               return ret;
-
-       }
-       private String normalisedVersion(String version, String sep, int maxWidth) {
-               String[] split = Pattern.compile(sep, Pattern.LITERAL).split(version);
-               StringBuilder sb = new StringBuilder();         
-               for (String s : split) {             
-                       sb.append(String.format("%" + maxWidth + 's', s));        
-               }        
-               return sb.toString();    
-       }
-
-       private boolean copyPackage(String source, String destination) {
-               boolean pushResult = false;
-               try {
-                       SyncService syncService = device.getSyncService();
-                       SyncResult pushSyncResult = syncService.pushFile(source, destination,
-                                       SyncService.getNullProgressMonitor());
-                       if (SyncService.RESULT_OK == pushSyncResult.getCode()) {
-                               pushResult = true;
-                       }
-               } catch (TimeoutException e) {
-                       return false;
-               } catch (SdbCommandRejectedException e) {
-                       return false;
-               } catch (IOException e) {
-                       return false;
-               }
-               return pushResult;
-       }
-
-       private final void installPackage(DebugTool tool) throws CoreException {
-               String local = DebugTool.TOOLS_HOST_PATH + "/" + tool.getSourcepath() + "/" + tool.getBinaryname();
-               String remote = DebugTool.TOOLS_TARGET_PATH + "/" + tool.getBinaryname();
-               
-               // delete old version
-               try {
-                       device.executeShellCommand(
-                                       "cd " + DebugTool.TOOLS_TARGET_PATH + " && rm " + tool.getControlFile());
-               } catch (IOException e) {
-                       installCoreException(ToolsInstallMessages.CANNOT_REMOVE_CONTROLFILE, e);
-                       Logger.error(ToolsInstallMessages.CANNOT_REMOVE_CONTROLFILE, e);
-               }
-               
-               
-               boolean isCopied = copyPackage(local, remote);
-               monitor.worked(5);
-               if (isCopied) {
-                       try {
-                               //make one string command for sequential executing
-                               device.executeShellCommand(
-                               "rm -rf " + DebugTool.TOOLS_TARGET_PATH + "/" + tool.getPackagename() + ";"
-                               + "cd " + DebugTool.TOOLS_TARGET_PATH + " && tar -xzf " + tool.getBinaryname() + ";"
-                               + "echo 'version:" + tool.getVersion() + "' >" + DebugTool.TOOLS_TARGET_PATH + "/" +                                            tool.getControlFile() + ";"
-                               + "cd " + DebugTool.TOOLS_TARGET_PATH + " && rm " + tool.getBinaryname());
-
-                       } catch (IOException e) {
-                               Logger.error("Error after copied " + tool.getPackagename() , e);
-                       }
-               }
-       }
-
-       @Override
-       public void run(IProgressMonitor pMonitor) throws InvocationTargetException, InterruptedException {
-               final List<DebugTool>  debugTools = ConnectionPlugin.getDebugTools(device);
-               
-               if (debugTools == null || debugTools.size() == 0)
-                       return;
-               boolean isInstalled = false;
-               for (int i = 0; i < debugTools.size(); i++) {
-                       DebugTool dt = (DebugTool) debugTools.get(i);
-                       try {
-                               isInstalled = isInstalled(dt);
-                       } catch (CoreException e) {
-                               Logger.error("Error to check installed", e);
-                       }
-                       if (isInstalled == false)
-                               break;
-               }
-               if (isInstalled)
-                       return;
-                       
-               this.monitor = pMonitor;
-               
-               pMonitor.beginTask(ToolsInstallMessages.DIALOG_INITILIZE, 100);
-               //monitor.subTask("Prepare install");
-               
-               // check directory exist
-               try {
-                       if (!checkDirectory(DebugTool.TOOLS_TARGET_PATH)) 
-                               makeDirectory(DebugTool.TOOLS_TARGET_PATH);
-               } catch (CoreException e) {
-                       Logger.error("Error to check or make directory", e);
-               }
-
-               pMonitor.worked(10);
-
-               // get package list to install
-               
-               pMonitor.worked(15);
-
-               // install loop (cp, tar)
-               for (int i=0 ; i<debugTools.size(); i++) {
-                       final DebugTool dt = (DebugTool)debugTools.get(i);
-                       
-                       if (device.isEmulator()) {
-                               if (!dt.getArchitecture().equals("i386"))
-                                       continue;
-                       }
-                       else {
-                               if (!dt.getArchitecture().equals("armel"))
-                                       continue;
-                       }
-                       Thread thread = new Thread(null, new Runnable() {
-
-                               @Override
-                               public void run() {
-                                               try {
-                                                       installPackage(dt);
-                                               } catch (CoreException e) {
-                                                       Logger.error("Error to install tools", e);
-                                               }
-                               }
-                       }, "package check and install");
-                       thread.start();
-               }
-               pMonitor.done();
-       }
-
-       public void setDevice(IDevice pDevice) {
-               device = pDevice;
-       }
-       
-       private void installCoreException(String message, Throwable exception) throws CoreException {
+    private static final String CMD_RESULT_CHECK = "; echo $?";
+    private static final String CMD_TAR_INSTALL =
+            "rm -rf " + TizenPlatformConstants.TOOLS_TARGET_PATH + "/%s && " +                    // remove old version package
+            "cd " + TizenPlatformConstants.TOOLS_TARGET_PATH + " && " +                              // move to directory for on-demand
+            "tar -xzf %s && " +                                                                                               // install new version package
+            "echo 'version:%s'>" + TizenPlatformConstants.TOOLS_TARGET_PATH + "/%s && " +  // create control file
+            "rm -f " + TizenPlatformConstants.TOOLS_TARGET_PATH + "/%s";                              // remove package.tar
+
+
+    private IDevice device = null;
+
+    IProgressMonitor monitor = null;
+
+    private boolean checkDirectory(String dir) throws CoreException {
+        String cmd = "ls " + dir + CMD_RESULT_CHECK;
+        return checkExitCode(cmd, ToolsInstallMessages.CANNOT_CHECK_DIRECTORY);
+    }
+
+
+    private void makeDirectory(String dir) throws CoreException {
+        String cmd = "mkdir -p -m 755 " + dir + CMD_RESULT_CHECK ;
+        String msg = ToolsInstallMessages.CANNOT_CREATE_DIRECTORY;
+
+        if (checkExitCode(cmd, msg) == false)
+        {
+            installCoreException(msg, null);
+        }
+    }
+
+    private boolean checkExitCode( String cmd, String msg ) throws CoreException
+    {
+        boolean result = false;
+        SdbShellProcess lsProc;
+        BufferedReader br = null;
+        try {
+            lsProc = device.executeShellCommand(cmd);
+            br = new BufferedReader(new InputStreamReader(
+                    lsProc.getInputStream()));
+            String lsOut = null;
+            while (null != (lsOut = br.readLine())) {
+                if ("0".equals(lsOut)) {
+                    result = true;
+                    break;
+                }
+            }
+        } catch (IOException e) {
+            installCoreException(msg, e);
+            Logger.error(msg, e);
+        }finally
+        {
+            tryClose( br );
+        }
+        return result;
+    }
+
+    private boolean isInstalled(DebugTool dt) throws CoreException {
+        boolean ret = false;
+        BufferedReader br = null;
+        try {
+
+            SdbShellProcess echoProc = device.executeShellCommand(
+                    "cat " + TizenPlatformConstants.TOOLS_TARGET_PATH + "/" + dt.getControlFile() + CMD_RESULT_CHECK);
+            br = new BufferedReader(new InputStreamReader(
+                    echoProc.getInputStream()));
+
+            String lsOut = null;
+            String oldVersion = null;
+            while (null != (lsOut = br.readLine())) {
+                //version:0.0.0
+                if (lsOut.toLowerCase().startsWith("version:")) {
+                    oldVersion = lsOut.split(":")[1];
+                }
+
+                if ("0".equals(lsOut)) {
+                    String v1 = normalisedVersion(oldVersion, ".", 4);
+                    String v2 = normalisedVersion(dt.getVersion(), ".", 4);
+                    if (v2.compareTo(v1) > 0) {
+                        //TODO : do install and save!
+                        ret = false;
+                    } else { //same version
+                        ret = true;
+                    }
+                    break;
+                } else
+                {
+                    ret = false;
+                }
+            }
+        } catch (IOException e) {
+            installCoreException(ToolsInstallMessages.CANNOT_CHECK_INSTALLED, e);
+            Logger.error(ToolsInstallMessages.CANNOT_CHECK_INSTALLED, e);
+        } finally {
+            tryClose( br );
+        }
+        return ret;
+
+    }
+    private String normalisedVersion(String version, String sep, int maxWidth) {
+        String[] split = Pattern.compile(sep, Pattern.LITERAL).split(version);
+        StringBuilder sb = new StringBuilder();
+        for (String s : split) {
+            sb.append(String.format("%" + maxWidth + 's', s));
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public void run(IProgressMonitor pMonitor) throws InvocationTargetException, InterruptedException {
+        final List<DebugTool>  allDebugTools = ConnectionPlugin.getDebugTools(device);
+        List<DebugTool> installDebugTools = new ArrayList<DebugTool>();
+
+        if ( isEmpty( allDebugTools ) )
+        {
+            return;
+        }
+        boolean isInstalled = false;
+        for ( DebugTool dt : allDebugTools ) {
+            try {
+                isInstalled = isInstalled(dt);
+            } catch (CoreException e) {
+                Logger.error("Error to check installed", e);
+            }
+            if (isInstalled == false) {
+                installDebugTools.add(dt);
+            }
+        }
+        if ( installDebugTools.isEmpty() ) {
+            return;
+        }
+
+        this.monitor = pMonitor;
+
+        pMonitor.beginTask(ToolsInstallMessages.DIALOG_INITILIZE, 100);
+        //monitor.subTask("Prepare install");
+
+        // check directory exist
+        try {
+            if (!checkDirectory(TizenPlatformConstants.TOOLS_TARGET_PATH))
+                makeDirectory(TizenPlatformConstants.TOOLS_TARGET_PATH);
+        } catch (CoreException e) {
+            Logger.error("Error to check or make directory", e);
+        }
+
+        pMonitor.worked(10);
+
+        // get package list to install
+
+        pMonitor.worked(15);
+        String threadName = "";
+        // install loop (cp, tar)
+        for ( DebugTool dt : installDebugTools ) {
+            if (device.isEmulator()) {
+                if (!dt.getArchitecture().contains("86"))
+                    continue;
+            }
+            else {
+                if (!dt.getArchitecture().contains("arm"))
+                    continue;
+            }
+            
+            threadName = "OnDemandInstallThread-" + dt.getPackagename();
+            Runnable r = new OnDemandInstall(dt);
+            Thread t = new Thread(r, threadName);
+            t.start();
+        }
+        pMonitor.done();
+    }
+
+    public void setDevice(IDevice pDevice) {
+        device = pDevice;
+    }
+    
+    private boolean copyPackage(String source, String destination) {
+        return SdbCommandUtil.filePush(device, source, destination);
+    }
+    
+    private final void installTarPackage(DebugTool tool) throws CoreException {
+        String local = DebugTool.TOOLS_HOST_PATH + "/" + tool.getSourcepath() + "/" + tool.getBinaryname();
+        String remote = TizenPlatformConstants.TOOLS_TARGET_PATH + "/" + tool.getBinaryname();
+
+        // delete old version
+        try {
+            device.executeShellCommand(
+                    "cd " + TizenPlatformConstants.TOOLS_TARGET_PATH + " && rm " + tool.getControlFile());
+        } catch (IOException e) {
+            Logger.error("Failed delete old version ( " + tool.getPackagename() + " )");
+            return;
+        }
+
+        boolean isCopied = copyPackage(local, remote);
+        if (isCopied) {
+            try {
+              //make one string command for sequential executing
+                String installCommand = String.format(CMD_TAR_INSTALL, tool.getPackagename(),
+                                                                                                      tool.getBinaryname(),
+                                                                                                      tool.getVersion(), tool.getControlFile(),
+                                                                                                      tool.getBinaryname());
+                device.executeShellCommand(installCommand);
+
+            } catch (IOException e) {
+                Logger.error("Error after copied " + tool.getPackagename() , e);
+            }
+        }
+        else if (!isCopied) {
+            Logger.error("Failed file copy ( " + tool.getBinaryname() + " )");
+        }
+    }
+
+    private final void installRPMPackage(DebugTool tool) throws CoreException {
+        boolean isInstalled = false;
+        String local = DebugTool.TOOLS_HOST_PATH + "/" + tool.getSourcepath() + "/" + tool.getBinaryname();
+        String remote = TizenPlatformConstants.TOOLS_TARGET_PATH + "/" + tool.getBinaryname();
+
+        String packagename;
+
+        BufferedReader br = null;
+        SdbShellProcess sdbShell = null;
+        try {
+            sdbShell = device.executeShellCommand(String.format( DebugTool.RPM_QUERY_COMMAND, "\"%{NAME}\\n\"", tool.getPackagename()));
+            br = new BufferedReader(new InputStreamReader(sdbShell.getInputStream()));
+
+            while (null != (packagename = br.readLine())) {
+                if ( tool.getPackagename().equals(packagename)){
+                    isInstalled = true;
+                    break;
+                }
+            }
+        } catch (IOException e1) {
+        } finally {
+            IOUtil.tryClose(br);
+            if ( sdbShell != null ) {
+                sdbShell.destroy();
+            }
+        }
+
+        boolean isCopied = copyPackage(local, remote);
+        if (isCopied) {
+            String command = null;
+            if ( isInstalled ) {
+                command = String.format(DebugTool.RPM_UPGRADE_COMMAND, remote);
+            }
+            else {
+                command = String.format(DebugTool.RPM_INSTALL_COMMAND, remote);
+            }
+            try {
+                command = command + String.format("; rm -f %s", remote);
+                device.executeShellCommand(command);
+            } catch (IOException e) {
+                Logger.error("Error occurred while executing rpm command " + command , e);
+            }
+        }
+        else if (!isCopied) {
+            Logger.error("Failed file copy ( " + tool.getBinaryname() + " )");
+        }
+    }
+
+    private void installCoreException(String message, Throwable exception) throws CoreException {
         Status status = new Status(Status.ERROR, ConnectionPlugin.PLUGIN_ID, message, exception);
         throw new CoreException(status);
     }
+    
+    class OnDemandInstall implements Runnable {
+        private final DebugTool tool;
+        
+        OnDemandInstall(final DebugTool tool) {
+            this.tool = tool;
+        }
+        
+        @Override
+        public void run() {
+            try {
+                if ( DebugTool.RPM_PACKAGE_TYPE.equals(tool.getPackagetype()) ) {
+                    installRPMPackage(tool);
+                }
+                else {
+                    installTarPackage(tool);
+                }
+            } catch (CoreException e) {
+                Logger.error("Error to install tools", e);
+            }
+        }
+    }
 }
 
 public class ToolsInstall {
 
-       public static void installPackages(IDevice device) {
-               final IDevice tDevice = device;
-
-               if (tDevice.isOffline()) {
-                       return;
-               }
-
-               Display.getDefault().asyncExec(new Runnable() {
-                       @Override
-                       public void run() {
-                               final PackageInstallMonitorDialog installDialog = new PackageInstallMonitorDialog(
-                                               Display.getDefault().getActiveShell());
-                               try {
-                                       InstallProgress installProgress = new InstallProgress();
-                                       installProgress.setDevice(tDevice);
-                                       installDialog.run(true, false, installProgress);
-                               } catch (InvocationTargetException e) {
-                                       return;
-                               } catch (InterruptedException e) {
-                                       return;
-                               }
-                       }
-               });
-
-       }
+    public static void installPackages(IDevice device) {
+        final IDevice tDevice = device;
+
+        if (tDevice.isOffline()) {
+            return;
+        }
+
+        Display.getDefault().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+                final PackageInstallMonitorDialog installDialog = new PackageInstallMonitorDialog(
+                        Display.getDefault().getActiveShell());
+                try {
+                    InstallProgress installProgress = new InstallProgress();
+                    installProgress.setDevice(tDevice);
+                    installDialog.run(true, false, installProgress);
+                } catch (InvocationTargetException e) {
+                    Logger.error("Failed on-demand install", e);
+                    return;
+                } catch (InterruptedException e) {
+                    Logger.error("Failed on-demand install", e);
+                    return;
+                }
+            }
+        });
+    }
 }
index 5d83979..f192516 100644 (file)
@@ -1,8 +1,6 @@
-\r
-DIALOG_INITILIZE=Connection Explorer is initializing now. It might take few minutes.\r
+DIALOG_INITILIZE=Connection Explorer is initializing. It can take a few minutes.\r
 CANNOT_CREATE_DIRECTORY=Cannot create sdk tools directory\r
 CANNOT_CHECK_DIRECTORY=Cannot check sdk tools directory\r
 CANNOT_CHECK_INSTALLED=Cannot check installed tools\r
-CANNOT_COPY_FILE=Cannot copy file\r
-CANNOT_REMOVE_CONTROLFILE=Cannot copy file\r
\r
+CANNOT_COPY_FILE=Cannot copy the file\r
+CANNOT_REMOVE_CONTROLFILE=Cannot delete the file\r
index 4aa5e2d..f469f27 100644 (file)
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* Hoon Kang <h245.kang@samsung.com>
-* Hyunsik Noh <hyunsik.noh@samsung.com>
-* 
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hoon Kang <h245.kang@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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
-*
-*/
+ * 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.common.connection.explorer;
 
 import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Tree;
-
 import org.tizen.sdblib.FileListingService;
 import org.tizen.sdblib.FileListingService.FileEntry;
-import org.tizen.sdblib.FileListingService.IListingReceiver;
 import org.tizen.sdblib.IDevice;
 import org.tizen.sdblib.SmartDevelopmentBridge;
 
-public class ConnectionExplorerContentProvider  implements ITreeContentProvider {
-       
-    private TreeViewer viewer;
-    private FileEntry rootEntry;
-    
-    private IListingReceiver listingReceiver = new IListingReceiver() {
-        public void setChildren(final FileEntry entry, FileEntry[] children) {
-            final Tree t = viewer.getTree();
-            if (t != null && t.isDisposed() == false) {
-                Display display = t.getDisplay();
-                if (display.isDisposed() == false) {
-                    display.asyncExec(new Runnable() {
-                        public void run() {
-                            if (t.isDisposed() == false) {
-                                // refresh the entry.
-                                viewer.refresh(entry);
-                                viewer.setExpandedState(entry, true);
-                            }
-                        }
-                    });
-                }
-            }
-        }
+public class ConnectionExplorerContentProvider implements ITreeContentProvider
+{
 
-        public void refreshEntry(final FileEntry entry) {
-            final Tree t = viewer.getTree();
-            if (t != null && t.isDisposed() == false) {
-                Display display = t.getDisplay();
-                if (display.isDisposed() == false) {
-                    display.asyncExec(new Runnable() {
-                        public void run() {
-                            if (t.isDisposed() == false) {
-                                // refresh the entry.
-                                viewer.refresh(entry);
-                            }
-                        }
-                    });
-                }
-            }
-        }
-    };
+    @Override
+    public void dispose()
+    {
+    }
 
-       
-       @Override
-       public void dispose() {
-       }
+    @Override
+    public void inputChanged(Viewer pViewer, Object pOldInput, Object pNewInput)
+    {
+    }
 
-       @Override
-       public void inputChanged(Viewer pViewer, Object pOldInput, Object pNewInput) {
-                if (pViewer instanceof TreeViewer) {
-                   viewer = (TreeViewer) pViewer;
-               }
-               if (pNewInput instanceof FileEntry) {
-                   rootEntry = (FileEntry) pNewInput;
-               }               
-       }
-
-       @Override
-       public Object[] getChildren(Object arg0) {
-        if (arg0 instanceof FileEntry) {
+    @Override
+    public Object[] getChildren(Object arg0)
+    {
+        if (arg0 instanceof FileEntry)
+        {
             FileEntry parentEntry = (FileEntry) arg0;
+            Object[] newEntries = parentEntry.getFileListingService().getChildren(parentEntry, false, null);
 
-            Object[] oldEntries = parentEntry.getCachedChildren();
-            Object[] newEntries = parentEntry.getFileListingService().getChildren(parentEntry,
-                    true, listingReceiver);
-
-            if (newEntries != null) {
+            if (newEntries != null)
+            {
                 return newEntries;
-            } else {
-                return oldEntries;
             }
         }
         return new Object[0];
-       }
+    }
 
-       @Override
-       public Object[] getElements(Object arg0) {
-                IDevice[] devices = SmartDevelopmentBridge.getBridge().getDevices();
-                FileEntry[] entries = new FileEntry[ devices.length ];
-                for (int i = 0; i < devices.length; i++) {
-                        entries[i] = devices[i].getFileListingService().getRoot();
+    @Override
+    public Object[] getElements(Object arg0)
+    {
+        IDevice[] devices = SmartDevelopmentBridge.getBridge().getDevices();
+        FileEntry[] entries = new FileEntry[devices.length];
+        for (int i = 0; i < devices.length; i++)
+        {
+            entries[i] = devices[i].getFileListingService().getRoot();
         }
         return entries;
-       }
+    }
 
-       @Override
-       public Object getParent(Object arg0) {
-        if (arg0 instanceof FileEntry) {
+    @Override
+    public Object getParent(Object arg0)
+    {
+        if (arg0 instanceof FileEntry)
+        {
             FileEntry entry = (FileEntry) arg0;
 
             return entry.getParent();
         }
         return null;
-       }
+    }
 
-       @Override
-       public boolean hasChildren(Object arg0) {
-               if (arg0 instanceof FileEntry) {
-                       FileEntry entry = (FileEntry) arg0;
-                       if (entry.getType() == FileListingService.TYPE_DIRECTORY_LINK)
-                               return true;
-                       else if (entry.getType() == FileListingService.TYPE_LINK)
-                               return true;
-                       else if (entry.getType() == FileListingService.TYPE_DIRECTORY)
-                               return true;
-                       else if (entry.getType() == FileListingService.TYPE_ROOT_EMULATOR)
-                               return true;
-                       else if (entry.getType() == FileListingService.TYPE_ROOT_DEVICE)
-                               return true;
-               }
-               return false;
-       }
-}
+    @Override
+    public boolean hasChildren(Object arg0)
+    {
+        if (arg0 instanceof FileEntry)
+        {
+            FileEntry entry = (FileEntry) arg0;
+            if (entry.getType() == FileListingService.TYPE_DIRECTORY_LINK)
+                return true;
+            else if (entry.getType() == FileListingService.TYPE_LINK)
+                return true;
+            else if (entry.getType() == FileListingService.TYPE_DIRECTORY)
+                return true;
+            else if (entry.getType() == FileListingService.TYPE_ROOT_EMULATOR)
+                return true;
+            else if (entry.getType() == FileListingService.TYPE_ROOT_DEVICE)
+                return true;
+        }
+        return false;
+    }
+}
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 3b8c5ca..c9a59c4
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* Hoon Kang <h245.kang@samsung.com>
-* Hyunsik Noh <hyunsik.noh@samsung.com>
-* 
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hoon Kang <h245.kang@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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
-*
-*/
+ * 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.common.connection.explorer;
 
 import org.eclipse.jface.viewers.ILabelProviderListener;
 import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Display;
-import org.tizen.common.connection.ddmuilib.ImageLoader;
-
+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.IDevice;
 
-public class ConnectionExplorerLabelProvider implements ITableLabelProvider {
+public class ConnectionExplorerLabelProvider implements ITableLabelProvider
+{
+
+    private final Image fileImage;
+    private final Image folderImage;
+    private final Image fileLinkImage;
+    private final Image folderLinkImage;
+    private final Image otherImage;
+    private final Image emulatorImage;
+    private final Image deviceImage;
+    public static int index;
+
+    public ConnectionExplorerLabelProvider(Display display)
+    {
+
+        fileImage = ConnectionPlugin.getImageDescriptorFromPlugin("icons/file.gif").createImage();
+        folderImage = ConnectionPlugin.getImageDescriptorFromPlugin("icons/directory.gif")
+                .createImage();
+        fileLinkImage = ConnectionPlugin.getImageDescriptorFromPlugin("icons/file_link.gif")
+                .createImage();
+        folderLinkImage = ConnectionPlugin.getImageDescriptorFromPlugin("icons/directory_link.gif")
+                .createImage();
+        otherImage = ConnectionPlugin.getImageDescriptorFromPlugin("icons/file.gif").createImage();
+        emulatorImage = ConnectionPlugin.getImageDescriptorFromPlugin("icons/emulator.gif")
+                .createImage();
+        deviceImage = ConnectionPlugin.getImageDescriptorFromPlugin("icons/device.gif")
+                .createImage();
+    }
 
-       private Image fileImage;
-       private Image folderImage;
-       private Image fileLinkImage;
-       private Image folderLinkImage;
-       private Image otherImage;
-       private Image emulatorImage;
-       private Image deviceImage;
-       public static int index;
-       public ConnectionExplorerLabelProvider(Display display) {
-               ImageLoader loader = ImageLoader.getDdmUiLibLoader();
-               
-               fileImage = loader.loadImage("file.gif", display);
-               folderImage = loader.loadImage("directory.gif", display);
-               fileLinkImage = loader.loadImage("file_link.gif", display);
-               folderLinkImage = loader.loadImage("directory_link.gif", display);
-               otherImage = loader.loadImage("file.gif", display);
-               emulatorImage = loader.loadImage("emulator.gif", display);
-               deviceImage = loader.loadImage("device.gif", display);
-       }
+    @Override
+    public Image getColumnImage(Object element, int columnIndex)
+    {
+        if (columnIndex == 0)
+        {
+            if (element instanceof FileEntry)
+            {
+                FileEntry entry = (FileEntry) element;
+                switch (entry.getType())
+                {
+                    case FileListingService.TYPE_FILE:
+                        return fileImage;
+                    case FileListingService.TYPE_LINK:
+                        return fileLinkImage;
+                    case FileListingService.TYPE_DIRECTORY:
+                        return folderImage;
+                    case FileListingService.TYPE_DIRECTORY_LINK:
+                        return folderLinkImage;
+                    case FileListingService.TYPE_ROOT_EMULATOR:
+                        return emulatorImage;
+                    case FileListingService.TYPE_ROOT_DEVICE:
+                        return deviceImage;
+                    default:
+                        return otherImage;
+                }
+            }
+        }
+        return null;
+    }
 
-       @Override
-       public Image getColumnImage(Object element, int columnIndex) {
-               if (columnIndex == 0) {
-                       if (element instanceof FileEntry) {
-                               FileEntry entry = (FileEntry) element;
-                               switch (entry.getType()) {
-                               case FileListingService.TYPE_FILE:
-                                       return fileImage;
-                               case FileListingService.TYPE_LINK:
-                                       return fileLinkImage;
-                               case FileListingService.TYPE_DIRECTORY:
-                                       return folderImage;
-                               case FileListingService.TYPE_DIRECTORY_LINK:
-                                       return folderLinkImage;
-                               case FileListingService.TYPE_ROOT_EMULATOR:
-                                       return emulatorImage;
-                               case FileListingService.TYPE_ROOT_DEVICE:
-                                       return deviceImage;
-                               default:
-                                       return null;
-                               }
-                       } 
+    @Override
+    public String getColumnText(Object element, int columnIndex)
+    {
+        if (element instanceof FileEntry)
+        {
+            FileEntry entry = (FileEntry) element;
 
-                       return otherImage;
-               }
-               return null;
-       }
+            switch (columnIndex)
+            {
+                case 0:
+                    if (entry.isRoot())
+                    {
+                        return getDeviceSerialWithName(entry);
+                    } else
+                    {
+                        return entry.getName();
+                    }
+                default:
+                    return null;
+            }
+        } else if (element instanceof IDevice)
+        {
+            IDevice device = (IDevice) element;
+            return device.getDeviceName();
+        }
+        return null;
+    }
 
-       @Override
-       public String getColumnText(Object element, int columnIndex) {
-               if (element instanceof FileEntry) {
-                       FileEntry entry = (FileEntry) element;
+    @Override
+    public void addListener(ILabelProviderListener listener)
+    {}
 
-                       switch (columnIndex) {
-                       case 0:
-                               return entry.getName();
-                       default:
-                               return null;
-                       }
-               } else if (element instanceof IDevice) {
-                       IDevice device = (IDevice) element;
-                       return device.getSerialNumber();
-               }
-               return null;
-       }
+    @Override
+    public void dispose()
+    {
+        SWTUtil.tryDispose(fileImage, folderImage, fileLinkImage, folderLinkImage, otherImage,
+                emulatorImage, deviceImage);
+    }
 
-       @Override
-       public void addListener(ILabelProviderListener listener) {
-       }
+    @Override
+    public boolean isLabelProperty(Object element, String property)
+    {
+        return false;
+    }
 
-       @Override
-       public void dispose() {
-       }
+    @Override
+    public void removeListener(ILabelProviderListener listener)
+    {}
 
-       @Override
-       public boolean isLabelProperty(Object element, String property) {
-               return false;
-       }
+    public static String getDeviceSerialWithName(IDevice device)
+    {
+        return combineSerialWithName(device.getSerialNumber(), device.getDeviceName());
+    }
 
-       @Override
-       public void removeListener(ILabelProviderListener listener) {
-       }
+    public static String getDeviceSerialWithName(FileEntry entry)
+    {
+        return combineSerialWithName(entry.getFileListingService().getDevice().getSerialNumber(), entry.getName());
+    }
+    
+    private static String combineSerialWithName(String serial, String name)
+    {
+        return String.format("%s (%s)", serial, name);
+    }
 
-}
+}
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 3f72e47..2478c1d
@@ -1,35 +1,35 @@
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* Hoon Kang <h245.kang@samsung.com>
-* Hyunsik Noh <hyunsik.noh@samsung.com>
-* 
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hoon Kang <h245.kang@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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
-*
-*/
+ * 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.common.connection.explorer;
 
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
-import java.util.regex.Pattern;
+import java.util.List;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
@@ -59,14 +59,19 @@ import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Dialog;
 import org.eclipse.swt.widgets.DirectoryDialog;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.FileDialog;
 import org.eclipse.swt.widgets.ToolItem;
 import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.console.MessageConsoleStream;
+import org.eclipse.ui.dialogs.PropertyDialogAction;
 import org.eclipse.ui.part.PluginTransfer;
 import org.eclipse.ui.part.PluginTransferData;
+import org.tizen.common.TizenPlatformConstants;
 import org.tizen.common.connection.ConnectionPlugin;
 import org.tizen.common.connection.ConnectionPlugin.ISelectionListener;
 import org.tizen.common.connection.ddmuilib.DdmUiPreferences;
@@ -74,13 +79,14 @@ import org.tizen.common.connection.ddmuilib.FileDialogUtils;
 import org.tizen.common.connection.ddmuilib.Panel;
 import org.tizen.common.connection.ddmuilib.SyncProgressMonitor;
 import org.tizen.common.connection.ddmuilib.TableHelper;
-import org.tizen.common.connection.ddmuilib.console.DdmConsole;
 import org.tizen.common.connection.debugtools.ToolsInstall;
 import org.tizen.common.connection.sdblib.dnd.FileEntryTransfer;
-import org.tizen.common.console.AnsicodeAdapter;
-import org.tizen.common.log.Logger;
-
-import org.tizen.sdblib.FileListingService;
+import org.tizen.common.connection.ui.ConnectionUIMessages;
+import org.tizen.common.ui.view.console.AnsicodeAdapter;
+import org.tizen.common.ui.view.console.ConsoleManager;
+import org.tizen.common.util.DialogUtil;
+import org.tizen.common.util.FilenameUtil;
+import org.tizen.common.util.log.Logger;
 import org.tizen.sdblib.FileListingService.FileEntry;
 import org.tizen.sdblib.IDevice;
 import org.tizen.sdblib.MultiLineReceiver;
@@ -91,1028 +97,1132 @@ import org.tizen.sdblib.SyncService;
 import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
 import org.tizen.sdblib.SyncService.SyncResult;
 
-public class ConnectionExplorerPanel extends Panel
-               implements
-                       IDeviceChangeListener,
-                       IDebugBridgeChangeListener,
-                       ISelectionListener {
-
-       private static final String DRAGACTIONID = "org.tizen.common.connection.filedrop";
-       private static final String INVALID_FOR_FILENAME = ";";
-
-       private static final String COLUMN_NAME = "name"; //$NON-NLS-1S
-       private static final String CMD_RESULT_CHECK = "; echo $?";
-
-       private Composite parent;
-       private TreeViewer treeViewer;
-       private Tree tree;
-       private ConnectionExplorerContentProvider mContentProvider;
-
-       private ToolItem pushToolItem;
-       private ToolItem pullToolItem;
-       private ToolItem emulStartToolItem;
-       
-       private MenuManager subMenu;
-       private Action actionPush;
-       private Action actionPull;
-       private Action actionRefresh;
-       private Action actionRename;
-       private Action actionProperty;
-       private Action actionDelete;
-
-       private IDevice mCurrentDevice;
-
-       private String defaultSave;
-       // only use on linux system
-       private static final String PATH_SEPARATOR = "/";
-
-       private final ArrayList<IDevice> devicesToExpand = new ArrayList<IDevice>();
-       private final ArrayList<IDevice> devicesList = new ArrayList<IDevice>();
-       private FileEntry currentFileEntry;
-
-       public ConnectionExplorerPanel() {
-       }
-
-       
-       @Override
-       protected Control createControl(Composite pParent) {
-               parent = pParent;
-               parent.setLayout(new FillLayout());
-
-               tree = new Tree(parent, SWT.MULTI | SWT.FULL_SELECTION);
-               tree.setHeaderVisible(true);
-
-               IPreferenceStore store = DdmUiPreferences.getStore();
-
-               TableHelper.createTreeColumn(tree, "FileEntry", SWT.LEFT,
-                               "abcdefghijklmnopqrstuvwzabcdefghijk", COLUMN_NAME, store); //$NON-NLS-1$
-               tree.setHeaderVisible(true);
-
-               treeViewer = new TreeViewer(tree);
-               mContentProvider = new ConnectionExplorerContentProvider();
-               treeViewer.setContentProvider(mContentProvider);
-               treeViewer.setLabelProvider(new ConnectionExplorerLabelProvider(
-                               parent.getDisplay()));
-
-               tree.addSelectionListener(new SelectionAdapter() {
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               notifyListeners();
-                       }
-               });
-
-               // setup drag listener
-               treeViewer.addDragSupport(
-                               DND.DROP_MOVE | DND.DROP_COPY,
-                               new Transfer[]{PluginTransfer.getInstance(),
-                                               FileEntryTransfer.getInstance()},
-                               new DragSourceListener() {
-
-                                       @Override
-                                       public void dragStart(DragSourceEvent e) {
-
-                                               TreeItem[] items = tree.getSelection();
-
-                                               for (int i = 0; i < items.length; i++) {
-                                                       Object data = items[i].getData();
-                                                       if (data instanceof FileEntry) {
-                                                               if (((FileEntry) data).isDirectory() == true || ((FileEntry) data).isRoot() == true) {
-                                                                       e.doit = false;
-                                                                       return;
-                                                               }
-                                                       }
-                                               }
-                                               e.doit = true;
-                                       }
-                                       @Override
-                                       public void dragFinished(DragSourceEvent arg0) {
-
-                                       }
-
-                                       @Override
-                                       public void dragSetData(DragSourceEvent e) {
-                                               // get the selection
-                                               TreeItem[] items = tree.getSelection();
-                                               FileEntry[] entries = new FileEntry[items.length];
-
-                                               for (int i = 0; i < items.length; i++) {
-                                                       Object data = items[i].getData();
-                                                       if (data instanceof FileEntry) {
-                                                               entries[i] = ((FileEntry) data);
-                                                       }
-                                               }
-
-                                               if (FileEntryTransfer.getInstance().isSupportedType(
-                                                               e.dataType)) {
-                                                       e.data = entries;
-                                               } else if (PluginTransfer.getInstance()
-                                                               .isSupportedType(e.dataType)) {
-                                                       byte[] data = FileEntryTransfer.getInstance()
-                                                                       .toByteArray(entries);
-                                                       e.data = new PluginTransferData(DRAGACTIONID, data);
-                                               }
-
-                                       }
-                               });
-               
-               // setup drop listener
-               treeViewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE,
-                               new Transfer[]{FileTransfer.getInstance()},
-                               new ViewerDropAdapter(treeViewer) {
-                                       @Override
-                                       public boolean performDrop(Object data) {
-                                               // get the item on which we dropped the item(s)
-                                               FileEntry target = (FileEntry) getCurrentTarget();
-
-                                               // in case we drop at the same level as root
-                                               if (target == null) {
-                                                       return false;
-                                               }
-
-                                               // if the target is not a directory, we get the parent
-                                               // directory
-                                               if (target.isDirectory() == false) {
-                                                       target = target.getParent();
-                                               }
-
-                                               if (target == null) {
-                                                       return false;
-                                               }
-
-                                               // get the list of files to drop
-                                               String[] files = (String[]) data;
-
-                                               // do the drop
-                                               pushFiles(files, target);
-
-                                               // we need to finish with a refresh
-                                               refresh(target);
-
-                                               return true;
-                                       }
-
-                                       @Override
-                                       public boolean validateDrop(Object target, int operation,
-                                                       TransferData transferType) {
-                                               if (target == null) {
-                                                       return false;
-                                               }
-
-                                               // convert to the real item
-                                               FileEntry targetEntry = (FileEntry) target;
-
-                                               // if the target is not a directory, we get the parent
-                                               // directory
-                                               if (targetEntry.isDirectory() == false) {
-                                                       target = targetEntry.getParent();
-                                               }
-
-                                               if (target == null) {
-                                                       return false;
-                                               }
-
-                                               return true;
-                                       }
-                               });
-
-               return tree;
-       }
-
-       public void setToolItems(ToolItem push, ToolItem pull, ToolItem start) {
-               pushToolItem = push;
-               pullToolItem = pull;
-               emulStartToolItem = start;
-       }
-
-       public void setActions(MenuManager pSubMenu, Action pActionPush, Action pActionPull, Action pActionRefresh,
-                       Action pActionRename, Action pActionProperty, Action pActionDelete) {
-               this.subMenu = pSubMenu;
-               this.actionPush = pActionPush;
-               this.actionPull = pActionPull;
-               this.actionRefresh = pActionRefresh;
-               this.actionRename = pActionRename;
-               this.actionProperty = pActionProperty;
-               this.actionDelete = pActionDelete;
-       }
-
-       @Override
-       protected void postCreation() {
-               ConnectionPlugin.getDefault().addSelectionListener(this);
-               SmartDevelopmentBridge sdbBridge = SmartDevelopmentBridge.getBridge();
-               SmartDevelopmentBridge.addDebugBridgeChangeListener(this);
-               SmartDevelopmentBridge.addDeviceChangeListener(this);
-
-               IDevice[] devices = null;
-               if (sdbBridge != null) {
-                       devices = sdbBridge.getDevices();
-               }
-               if (devices != null && devices.length != 0) {
-                       for (IDevice device : devices) {
-                               this.deviceConnected(device);
-                       }
-               }
-       }
-
-       /**
-        * Sets the focus to the proper control inside the panel.
-        */
-       @Override
-       public void setFocus() {
-               tree.setFocus();
-       }
-
-       /**
-        * Pull the current selection on the local drive. This method displays a
-        * dialog box to let the user select where to store the file(s) and
-        * folder(s).
-        */
-       public void pullSelection() {
-               // get the selection
-               TreeItem[] items = tree.getSelection();
-
-               // name of the single file pull, or null if we're pulling a directory
-               // or more than one object.
-               String filePullName = null;
-               FileEntry singleEntry = null;
-
-               //Pull the single file
-               if (items.length == 1) {
-                       singleEntry = (FileEntry) items[0].getData();
-                       if (singleEntry.getType() == FileListingService.TYPE_FILE) {
-                               filePullName = singleEntry.getName();
-                       }
-               }
-
-               // where do we save by default?
-               String defaultPath = defaultSave;
-               if (defaultPath == null) {
-                       defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
-               }
-
-               if (filePullName != null) {
-                       FileDialog fileDialog = new FileDialog(parent.getShell(), SWT.SAVE);
-
-                       fileDialog.setText("Pull the Selection");
-                       fileDialog.setFileName(filePullName);
-                       fileDialog.setFilterPath(defaultPath);
-
-                       String fileName = fileDialog.open();
-                       if (fileName != null) {
-                               defaultSave = fileDialog.getFilterPath();
-
-                               pullFile(singleEntry, fileName);
-                       }
-               } else {
-                       DirectoryDialog directoryDialog = new DirectoryDialog(
-                                       parent.getShell(), SWT.SAVE);
-
-                       directoryDialog.setText("Pull the Selection");
-                       directoryDialog.setFilterPath(defaultPath);
-
-                       String directoryName = directoryDialog.open();
-                       if (directoryName != null) {
-                               pullSelection(items, directoryName);
-                       }
-               }
-       }
-
-       /**
-        * Push new file(s) and folder(s) into the current selection. Current
-        * selection must be single item. If the current selection is not a
-        * directory, the ` directory is used. This method displays a dialog to
-        * let the user choose file to push to the device.
-        */
-       public void pushIntoSelection() {
-               // get the name of the object we're going to pull
-               TreeItem[] items = tree.getSelection();
-
-               if (items.length == 0) {
-                       return;
-               }
-
-               FileDialog dlg = new FileDialog(parent.getShell(), SWT.OPEN);
-               String fileName;
-
-               dlg.setText("Push the Files");
-
-               // There should be only one.
-               FileEntry entry = (FileEntry) items[0].getData();
-
-               String defaultPath = defaultSave;
-               if (defaultPath == null) {
-                       defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
-               }
-               dlg.setFilterPath(defaultPath);
-
-               fileName = dlg.open();
-               if (fileName != null) {
-                       defaultSave = dlg.getFilterPath();
-
-                       // we need to figure out the remote path based on the current
-                       // selection type.
-                       String remotePath;
-                       FileEntry toRefresh = entry;
-                       if (entry.isDirectory() || entry.isRoot()) {
-                               remotePath = entry.getFullPath();
-                       } else {
-                               toRefresh = entry.getParent();
-                               remotePath = toRefresh.getFullPath();
-                       }
-
-                       pushFile(fileName, remotePath);
-                       treeViewer.refresh(toRefresh);
-               }
-       }
-
-       public void addNewFileSelection() {
-               InputDialog addNewDialog = new InputDialog(Display.getCurrent()
-                               .getActiveShell(), "New File Resource", "New File Name: ", "",
-                               new FileNameValidator());
-               if (addNewDialog.open() != Window.OK)
-                       return;
-
-               String fullPath = currentFileEntry.getFullPath();
-
-               TreeItem[] items = tree.getSelection();
-
-               if (items.length != 1) {
-                       return;
-               }
-
-               final FileEntry parentEntry = ((FileEntry) items[0].getData())
-                               .getParent();
-               // create the touch command
-               String command = "touch " + fullPath + PATH_SEPARATOR + addNewDialog.getValue() + CMD_RESULT_CHECK; //$NON-NLS-1$
-
-               try {
-                       mCurrentDevice.executeShellCommand(command,
-                                       new MultiLineReceiver() {
-
-                               @Override
-                               public void processNewLines(String[] lines) {
-                                       if(!lines[lines.length - 1].contains("0"))
-                                       {
-                                       StringBuilder sb = new StringBuilder();
-                                       for (String line : lines) {
-                                               line = AnsicodeAdapter.getStripAnsiString(line);        
-                                               sb.append(line);
-                                       
-                               }
-                                       Status status = new Status(IStatus.ERROR, "Add File Failed", 0,
-                                                       sb.toString() , null);
-                                       ErrorDialog.openError(Display.getCurrent().getActiveShell(), "Add File Failed", "A file failed to be added", status);
-                                       
-                       
-                               }
-                               }
-                       });
-               } catch (IOException e) {
-                       Logger.error("failed to do add new file", e);
-                       throw new RuntimeException(e);
-               }
-               refresh(parentEntry);
-       }
-
-       public void addNewFolderSelection() {
-               InputDialog addNewDialog = new InputDialog(Display.getCurrent()
-                               .getActiveShell(), "New Folder Resource", "New Folder Name: ",
-                               "", null);
-               if (addNewDialog.open() != Window.OK)
-                       return;
-               String fullPath = currentFileEntry.getFullPath();
-
-               TreeItem[] items = tree.getSelection();
-
-               if (items.length != 1) {
-                       return;
-               }
-
-               final FileEntry parentEntry = ((FileEntry) items[0].getData())
-                               .getParent();
-               // create the mkdir command
-               String command = "mkdir " + fullPath + PATH_SEPARATOR + addNewDialog.getValue() + CMD_RESULT_CHECK; //$NON-NLS-1$
-               try {
-                       mCurrentDevice.executeShellCommand(command,
-                                       new MultiLineReceiver() {
-
-                                               @Override
-                                               public void processNewLines(String[] lines) {
-                                                       if(!lines[lines.length - 1].contains("0"))
-                                                       {
-                                                       StringBuilder sb = new StringBuilder();
-                                                       for (String line : lines) {
-                                                               line = AnsicodeAdapter.getStripAnsiString(line);        
-                                                               sb.append(line);
-                                                       
-                                               }
-                                                       Status status = new Status(IStatus.ERROR, "Add Folder Failed", 0,
-                                                                       sb.toString() , null);
-                                                       ErrorDialog.openError(Display.getCurrent().getActiveShell(), "Add Folder Failed", "A folder failed to be added", status);
-                                               }
-                                               }
-                                       });
-               } catch (IOException e) {
-                       Logger.error("failed to do add new folder", e);
-                       throw new RuntimeException(e);
-               }
-               refresh(parentEntry);
-       }
-
-       public void renameSelection() {
-               InputDialog renameDialog = new InputDialog(Display.getCurrent()
-                               .getActiveShell(), "Rename Resource", "New name: ",
-                               currentFileEntry.getName(), new FileNameValidator());
-               if (renameDialog.open() != Window.OK)
-                       return;
-
-               String fullPath = currentFileEntry.getFullPath();
-               int lastIndex = fullPath.lastIndexOf(PATH_SEPARATOR);
-               String newPath = fullPath.substring(0, lastIndex) + PATH_SEPARATOR + renameDialog.getValue();
-
-               TreeItem[] items = tree.getSelection();
-
-               if (items.length != 1) {
-                       return;
-               }
-
-               final FileEntry parentEntry = ((FileEntry) items[0].getData())
-                               .getParent();
-               // create the mv command
-               String command = "mv " + fullPath + " " + newPath + CMD_RESULT_CHECK; //$NON-NLS-1$
-
-               try {
-                       mCurrentDevice.executeShellCommand(command,
-                                       new MultiLineReceiver() {
-
-                               @Override
-                               public void processNewLines(String[] lines) {
-                                       if(!lines[lines.length - 1].contains("0"))
-                                       {
-                                       StringBuilder sb = new StringBuilder();
-                                       for (String line : lines) {
-                                               line = AnsicodeAdapter.getStripAnsiString(line);        
-                                               sb.append(line);
-                                       
-                               }
-                                       Status status = new Status(IStatus.ERROR, "Rename failed", 0,
-                                                       sb.toString() , null);
-                                       ErrorDialog.openError(Display.getCurrent().getActiveShell(),  "Rename failed", "A selection failed to be renamed",status);
-                               }
-                               }
-                       });
-               } catch (IOException e) {
-                       Logger.error("failed to do rename", e);
-                       throw new RuntimeException(e);
-               }
-               refresh(parentEntry);
-       }
-
-       public void deleteSelection() {
-               int ret = FileDialogUtils.getInstance().confirmDelete(
-                               currentFileEntry.getName());
-               if (ret == IDialogConstants.CANCEL_ID)
-                       return;
-
-               TreeItem[] items = tree.getSelection();
-
-               for (TreeItem item : items) {
-                       final FileEntry entry = (FileEntry) item.getData();
-                       String command = null;
-                       // create the delete command
-                       if (entry.isDirectory()) {
-                               command = "rm -rf " + entry.getFullEscapedPath() + CMD_RESULT_CHECK; //$NON-NLS-1$
-                       } else {
-                               command = "rm " + entry.getFullEscapedPath() + CMD_RESULT_CHECK; //$NON-NLS-1$
-                       }
-
-                       try {
-                               mCurrentDevice.executeShellCommand(command,
-                                               new MultiLineReceiver() {
-
-                                       @Override
-                                       public void processNewLines(String[] lines) {
-                                               if(!lines[lines.length - 1].contains("0"))
-                                               {
-                                               StringBuilder sb = new StringBuilder();
-                                               for (String line : lines) {
-                                                       line = AnsicodeAdapter.getStripAnsiString(line);        
-                                                       sb.append(line);                                                
-                                               }
-                                               Status status = new Status(IStatus.ERROR, "Delete Failed", 0,
-                                                               sb.toString() , null);
-                                               ErrorDialog.openError(Display.getCurrent().getActiveShell(), "Delete failed", "A selection failed to be deleted", status);
-                                               }
-                                       }
-                               });
-                       } catch (IOException e) {
-                               Logger.error("failed to do delete", e);
-                               throw new RuntimeException(e);
-
-                       }
-                       refresh(entry.getParent());
-               }
-
-       }
-
-       /**
-        * Force a full refresh of the explorer.
-        */
-       public void refresh() {
-               treeViewer.refresh(true);
-       }
-
-       /**
-        * Sent when a new {@link SmartDevelopmentBridge} is started.
-        * <p/>
-        * This is sent from a non UI thread.
-        * 
-        * @param bridge
-        *            the new {@link SmartDevelopmentBridge} object.
-        * 
-        * @see IDebugBridgeChangeListener#serverChanged(SmartDevelopmentBridge)
-        */
-       public void bridgeChanged(final SmartDevelopmentBridge bridge) {
-               if (tree.isDisposed() == false) {
-                       exec(new Runnable() {
-                               public void run() {
-                                       if (tree.isDisposed() == false) {
-                                               // set up the data source.
-                                               treeViewer.setInput(bridge);
-
-                                       } else {
-                                               // tree is disposed, we need to do something.
-                                               // lets remove ourselves from the listener.
-                                               SmartDevelopmentBridge
-                                                               .removeDebugBridgeChangeListener(ConnectionExplorerPanel.this);
-                                               SmartDevelopmentBridge
-                                                               .removeDeviceChangeListener(ConnectionExplorerPanel.this);
-                                       }
-                               }
-                       });
-               }
-
-               // all current devices are obsolete
-               synchronized (devicesToExpand) {
-                       devicesToExpand.clear();
-               }
-       }
-
-       /**
-        * Refresh an entry from a non ui thread.
-        * 
-        * @param entry
-        *            the entry to refresh.
-        */
-       private void refresh(final FileEntry entry) {
-               Display d = treeViewer.getTree().getDisplay();
-               d.asyncExec(new Runnable() {
-                       public void run() {
-                               treeViewer.refresh(entry);
-                       }
-               });
-       }
-       public void refreshSelection() {
-               if (currentFileEntry == null)
-                       return;
-               Display d = treeViewer.getTree().getDisplay();
-               d.asyncExec(new Runnable() {
-                       public void run() {
-                               treeViewer.refresh(currentFileEntry);
-                       }
-               });
-       }
-
-       /**
-        * Pulls the selection from a device.
-        * 
-        * @param items
-        *            the tree selection the remote file on the device
-        * @param localDirector
-        *            the local directory in which to save the files.
-        */
-       private void pullSelection(TreeItem[] items, final String localDirectory) {
-               try {
-                       final SyncService sync = mCurrentDevice.getSyncService();
-                       if (sync != null) {
-                               // make a list of the FileEntry.
-                               ArrayList<FileEntry> entries = new ArrayList<FileEntry>();
-                               for (TreeItem item : items) {
-                                       Object data = item.getData();
-                                       if (data instanceof FileEntry) {
-                                               entries.add((FileEntry) data);
-                                       }
-                               }
-                               final FileEntry[] entryArray = entries
-                                               .toArray(new FileEntry[entries.size()]);
-
-                               // get a progress dialog
-                               new ProgressMonitorDialog(parent.getShell()).run(true, true,
-                                               new IRunnableWithProgress() {
-                                                       public void run(IProgressMonitor monitor)
-                                                                       throws InvocationTargetException,
-                                                                       InterruptedException {
-                                                               // create a monitor wrapper around the jface
-                                                               // monitor
-                                                               SyncResult result = sync
-                                                                               .pull(entryArray,
-                                                                                               localDirectory,
-                                                                                               (ISyncProgressMonitor) new SyncProgressMonitor(
-                                                                                                               monitor,
-                                                                                                               "Pulling file(s) from the device"));
-
-                                                               if (result.getCode() != SyncService.RESULT_OK) {
-                                                                       DdmConsole.printErrorToConsole(String
-                                                                                       .format("Failed to pull selection: %1$s",
-                                                                                                       result.getMessage()));
-                                                               }
-                                                               sync.close();
-                                                       }
-                                               });
-                       }
-               } catch (Exception e) {
-                       DdmConsole.printErrorToConsole("Failed to pull selection");
-                       DdmConsole.printErrorToConsole(e.getMessage());
-               }
-       }
-
-       /**
-        * Pulls a file from a device.
-        * 
-        * @param remote
-        *            the remote file on the device
-        * @param local
-        *            the destination filepath
-        */
-       private void pullFile(final FileEntry remote, final String local) {
-               try {
-                       final SyncService sync = mCurrentDevice.getSyncService();
-                       if (sync != null) {
-                               new ProgressMonitorDialog(parent.getShell()).run(true, true,
-                                               new IRunnableWithProgress() {
-                                                       public void run(IProgressMonitor monitor)
-                                                                       throws InvocationTargetException,
-                                                                       InterruptedException {
-                                                               SyncResult result = sync
-                                                                               .pullFile(
-                                                                                               remote,
-                                                                                               local,
-                                                                                               (ISyncProgressMonitor) new SyncProgressMonitor(
-                                                                                                               monitor,
-                                                                                                               String.format(
-                                                                                                                               "Pulling %1$s from the device",
-                                                                                                                               remote.getName())));
-                                                               if (result.getCode() != SyncService.RESULT_OK) {
-                                                                       DdmConsole.printErrorToConsole(String
-                                                                                       .format("Failed to pull %1$s: %2$s",
-                                                                                                       remote, result.getMessage()));
-                                                               }
-
-                                                               sync.close();
-                                                       }
-                                               });
-                       }
-               } catch (Exception e) {
-                       DdmConsole.printErrorToConsole("Failed to pull selection");
-                       DdmConsole.printErrorToConsole(e.getMessage());
-               }
-       }
-
-       /**
-        * Pushes several files and directory into a remote directory.
-        * 
-        * @param localFiles
-        * @param remoteDirectory
-        */
-       private void pushFiles(final String[] localFiles,
-                       final FileEntry remoteDirectory) {
-               try {
-                       final SyncService sync = mCurrentDevice.getSyncService();
-                       if (sync != null) {
-                               new ProgressMonitorDialog(parent.getShell()).run(true, true,
-                                               new IRunnableWithProgress() {
-                                                       public void run(IProgressMonitor monitor)
-                                                                       throws InvocationTargetException,
-                                                                       InterruptedException {
-                                                               SyncResult result = sync
-                                                                               .push(localFiles,
-                                                                                               remoteDirectory,
-                                                                                               (ISyncProgressMonitor) new SyncProgressMonitor(
-                                                                                                               monitor,
-                                                                                                               "Pushing file(s) to the device"));
-                                                               if (result.getCode() != SyncService.RESULT_OK) {
-                                                                       DdmConsole.printErrorToConsole(String
-                                                                                       .format("Failed to push the items: %1$s",
-                                                                                                       result.getMessage()));
-                                                               }
-
-                                                               sync.close();
-                                                       }
-                                               });
-                       }
-               } catch (Exception e) {
-                       DdmConsole.printErrorToConsole("Failed to push the items");
-                       DdmConsole.printErrorToConsole(e.getMessage());
-               }
-       }
-
-       /**
-        * Pushes a file on a device.
-        * 
-        * @param local
-        *            the local file path of the file to push
-        * @param remoteDirectory
-        *            the remote destination directory on the device
-        */
-       private void pushFile(final String local, final String remoteDirectory) {
-               try {
-                       final SyncService sync = mCurrentDevice.getSyncService();
-                       if (sync != null) {
-                               new ProgressMonitorDialog(parent.getShell()).run(true, true,
-                                               new IRunnableWithProgress() {
-                                                       public void run(IProgressMonitor monitor)
-                                                                       throws InvocationTargetException,
-                                                                       InterruptedException {
-                                                               // get the file name
-                                                               String[] segs = local.split(Pattern
-                                                                               .quote(File.separator));
-                                                               String name = segs[segs.length - 1];
-                                                               String remoteFile = remoteDirectory + FileListingService.FILE_SEPARATOR + name;
-
-                                                               SyncResult result = sync
-                                                                               .pushFile(
-                                                                                               local,
-                                                                                               remoteFile,
-                                                                                               (ISyncProgressMonitor) new SyncProgressMonitor(
-                                                                                                               monitor,
-                                                                                                               String.format(
-                                                                                                                               "Pushing %1$s to the device.",
-                                                                                                                               name)));
-                                                               if (result.getCode() != SyncService.RESULT_OK) {
-                                                                       DdmConsole.printErrorToConsole(String
-                                                                                       .format("Failed to push %1$s on %2$s: %3$s",
-                                                                                                       name, mCurrentDevice
-                                                                                                                       .getSerialNumber(),
-                                                                                                       result.getMessage()));
-                                                               }
-
-                                                               sync.close();
-                                                       }
-                                               });
-                       }
-               } catch (Exception e) {
-                       DdmConsole.printErrorToConsole("Failed to push the item(s).");
-                       DdmConsole.printErrorToConsole(e.getMessage());
-               }
-       }
-
-       /**
-        * 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.
-        * 
-        * @see IDeviceChangeListener#deviceConnected(IDevice)
-        */
-       public void deviceConnected(IDevice device) {
-               if (device.isOffline())
-                       return;
-               devicesList.add(device);
-               ToolsInstall.installPackages(device);
-               
-               exec(new Runnable() {
-                       public void run() {
-                               if (tree.isDisposed() == false) {
-                                       // refresh all
-                                       treeViewer.refresh();
-
-                                       // notify the listener of a possible selection change.
-                                       notifyListeners();
-                               } else {
-                                       // tree is disposed, we need to do something.
-                                       // lets remove ourselves from the listener.
-                                       SmartDevelopmentBridge
-                                                       .removeDebugBridgeChangeListener(ConnectionExplorerPanel.this);
-                                       SmartDevelopmentBridge
-                                                       .removeDeviceChangeListener(ConnectionExplorerPanel.this);
-                               }
-                       }
-               });
-
-               synchronized (devicesToExpand) {
-                       devicesToExpand.add(device);
-               }
-
-       }
-
-       @Override
-       public void deviceDisconnected(IDevice device) {
-               devicesList.remove(device);
-               exec(new Runnable() {
-                       public void run() {
-                               if (tree.isDisposed() == false) {
-                                       // refresh all
-                                       treeViewer.refresh();
-
-                                       // notify the listener of a possible selection change.
-                                       notifyListeners();
-                               } else {
-                                       // tree is disposed, we need to do something.
-                                       // lets remove ourselves from the listener.
-                                       SmartDevelopmentBridge
-                                                       .removeDebugBridgeChangeListener(ConnectionExplorerPanel.this);
-                                       SmartDevelopmentBridge
-                                                       .removeDeviceChangeListener(ConnectionExplorerPanel.this);
-                               }
-                       }
-               });
-
-               synchronized (devicesToExpand) {
-                       devicesToExpand.add(device);
-               }
-               // }
-       }
-
-       @Override
-       public void deviceChanged(IDevice device, int changeMask) {
-               if (changeMask == 1) {
-                       devicesList.add(device);
-                       ToolsInstall.installPackages(device);
-                       exec(new Runnable() {
-                               public void run() {
-                                       if (tree.isDisposed() == false) {
-                                               // refresh all
-                                               treeViewer.refresh();
-
-                                               // notify the listener of a possible selection change.
-                                               notifyListeners();
-                                       } else {
-                                               // tree is disposed, we need to do something.
-                                               // lets remove ourselves from the listener.
-                                               SmartDevelopmentBridge
-                                                               .removeDebugBridgeChangeListener(ConnectionExplorerPanel.this);
-                                               SmartDevelopmentBridge
-                                                               .removeDeviceChangeListener(ConnectionExplorerPanel.this);
-                                       }
-                               }
-                       });
-
-                       synchronized (devicesToExpand) {
-                               devicesToExpand.add(device);
-                       }
-               }
-       }
-
-       public ArrayList<IDevice> getDeviceList() {
-               return devicesList;
-       }
-
-       private void exec(Runnable runnable) {
-               if (tree.isDisposed() == false) {
-               try {
-                       Display display = tree.getDisplay();
-                       display.asyncExec(runnable);
-               } catch (SWTException e) {
-                       // tree is disposed, we need to do something. lets remove ourselves
-                       // from the listener.
-                       SmartDevelopmentBridge
-                                       .removeDebugBridgeChangeListener(ConnectionExplorerPanel.this);
-                       SmartDevelopmentBridge
-                                       .removeDeviceChangeListener(ConnectionExplorerPanel.this);
-               }
-               }
-       }
-
-       private void notifyListeners() {
-               // get the selection
-               TreeItem[] items = tree.getSelection();
-
-               FileEntry file = null;
-
-               if (items.length != 0) {
-                       Object object = items[0].getData();
-                       if (object instanceof FileEntry) {
-                               file = (FileEntry) object;
-                       }
-               }
-               notifySelectionListeners(file);
-       }
-
-       private void notifySelectionListeners(FileEntry file) {
-               if (file != null) {
-                       mCurrentDevice = file.getFileListingService().getDevice();
-               } else {
-                       IDevice[] devices = SmartDevelopmentBridge.getBridge().getDevices();
-                       if (devices.length != 0) {
-                               mCurrentDevice = devices[0];
-                               file = devices[0].getFileListingService().getRoot();
-                               for (TreeItem item : tree.getItems()) {
-                                if (item.getText().equals(file.getName()))
-                                tree.setSelection(item);
-                                }
-                       } else
-                               mCurrentDevice = null;
-               }
-               currentFileEntry = file;
-               ConnectionPlugin.getDefault().setCurrentDevice(mCurrentDevice);
-               ConnectionPlugin.getDefault().notifySelectionListeners(file);
-               setIconEnabled();
-       }
-       
-       public TreeViewer getTreeViewer() {
-               return treeViewer;
-       }
-
-       class FileNameValidator implements IInputValidator {
-
-               @Override
-               public String isValid(String newText) {
-                       if (newText.contains(INVALID_FOR_FILENAME))
-                               return "\"" + INVALID_FOR_FILENAME + "\" is invalid character for file name.";
-                       return null;
-               }
-       }
-
-       public void setActionState() {
-               subMenu.setVisible(true);
-               actionPush.setEnabled(true);
-               actionPull.setEnabled(true);
-               actionRename.setEnabled(true);
-               actionRefresh.setEnabled(true);
-               actionDelete.setEnabled(true);
-               actionProperty.setEnabled(true);
-
-               if (currentFileEntry == null) {
-                       subMenu.setVisible(false);
-                       actionPush.setEnabled(false);
-                       actionPull.setEnabled(false);
-                       actionRename.setEnabled(false);
-                       actionRefresh.setEnabled(false);
-                       actionDelete.setEnabled(false);
-                       actionProperty.setEnabled(false);
-                       return;
-               }
-               if (currentFileEntry.isRoot()) {
-                       actionPull.setEnabled(false);
-                       actionRename.setEnabled(false);
-                       actionDelete.setEnabled(false);
-                       return;
-               }
-               if (!currentFileEntry.isDirectory()) {
-                       subMenu.setVisible(false);
-                       actionPush.setEnabled(false);
-                       return;
-               }
-       }
-
-       private void setIconEnabled() {
-               boolean bPush = false;
-               boolean bPull = false;
-
-               if (currentFileEntry == null) {
-                       bPush = false;
-                       bPull = false;
-               } else {
-                       if (currentFileEntry.isRoot()) {
-                               bPush = true;
-                               bPull = false;                          
-                       } else if (!currentFileEntry.isDirectory()) {
-                               bPush = false;
-                               bPull = true;
-                       } else  {
-                               bPush = true;
-                               bPull = true;
-                               }
-               }
-
-               pushToolItem.setEnabled(bPush);
-               pullToolItem.setEnabled(bPull);
-
-       }
-
-       @Override
-       public void selectionChanged(final FileEntry selectedEntry) {
-                       if (selectedEntry == null)
-                               return;
-                       
-                       if (!selectedEntry.isRoot())
-                               return;
-                       
-                       exec(new Runnable() {
-                               public void run() {
-                                       if (tree.isDisposed() == false) {
-                                               for (TreeItem item : tree.getItems()) {
-                                                       if (item.getText().equals(selectedEntry.getName()))
-                                                               tree.setSelection(item);
-                                               }
-                                       } else {
-                                               // tree is disposed, we need to do something.
-                                               // lets remove ourselves from the listener.
-                                               ConnectionPlugin.getDefault().removeSelectionListener(ConnectionExplorerPanel.this);
-                                       }
-                               }
-                       });
-       }
+public class ConnectionExplorerPanel extends Panel implements IDeviceChangeListener, IDebugBridgeChangeListener, ISelectionListener
+{
+
+    private static final String DRAGACTIONID = "org.tizen.common.connection.filedrop";
+
+    private static final String COLUMN_NAME = "name"; //$NON-NLS-1S
+
+    private Composite parent;
+    private TreeViewer treeViewer;
+    private ConnectionExplorerContentProvider contentProvider;
+    
+    private final int STATE_PROPERTY = 0x0000001;
+    private final int STATE_DELETE = 0x0000010;
+    private final int STATE_RENAME = 0x0000100; 
+    private final int STATE_REFRESH = 0x0001000;
+    private final int STATE_PULL = 0x0010000;
+    private final int STATE_PUSH = 0x0100000;
+    private final int STATE_SUB = 0x1000000;
+
+    private ToolItem pushToolItem;
+    private ToolItem pullToolItem;
+    private ToolItem emulStartToolItem;
+
+    private MenuManager subMenu;
+    private Action actionPush;
+    private Action actionPull;
+    private Action actionRefresh;
+    private Action actionRename;
+    private Action actionProperty;
+    private Action actionDelete;
+
+    private IDevice currentDevice;
+
+    private String defaultSave;
+    // only use on linux system
+    private static final String PATH_SEPARATOR = "/";
+
+    private final List<IDevice> devicesList = new ArrayList<IDevice>();
+
+    private final MessageConsoleStream console;
+
+    public ConnectionExplorerPanel()
+    {
+        ConsoleManager cm = new ConsoleManager("ConnectionExplorer", false);
+        cm.clear();
+        console = cm.getMessageConsoleStream();
+    }
+
+    @Override
+    protected Control createControl(Composite pParent)
+    {
+        parent = pParent;
+        parent.setLayout(new FillLayout());
+
+        treeViewer = new TreeViewer(parent, SWT.MULTI | SWT.FULL_SELECTION);
+        Tree tree = treeViewer.getTree();
+        IPreferenceStore store = DdmUiPreferences.getStore();
+
+        TableHelper.createTreeColumn(tree, Messages.getString("ConnectionExplorer.tree.header"), SWT.LEFT, "abcdefghijklmnopqrstuvwzabcdefghijk", COLUMN_NAME, store); //$NON-NLS-1$
+        tree.setHeaderVisible(true);
+
+        contentProvider = new ConnectionExplorerContentProvider();
+        treeViewer.setContentProvider(contentProvider);
+        treeViewer.setLabelProvider(new ConnectionExplorerLabelProvider(parent.getDisplay()));
+
+        tree.addSelectionListener(new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e)
+            {
+                // set device for selected FileEntry when select FileEntry on
+                // tree
+                notifyListeners();
+            }
+        });
+
+        // setup drag listener
+        treeViewer.addDragSupport(DND.DROP_MOVE | DND.DROP_COPY, new Transfer[] { PluginTransfer.getInstance(), FileEntryTransfer.getInstance() },
+                new DragSourceListener()
+                {
+
+                    @Override
+                    public void dragStart(DragSourceEvent e)
+                    {
+
+                        TreeItem[] items = treeViewer.getTree().getSelection();
+
+                        for (int i = 0; i < items.length; i++)
+                        {
+                            Object data = items[i].getData();
+                            if (data instanceof FileEntry)
+                            {
+                                if (((FileEntry) data).isDirectory() == true || ((FileEntry) data).isRoot() == true)
+                                {
+                                    e.doit = false;
+                                    return;
+                                }
+                            }
+                        }
+                        e.doit = true;
+                    }
+
+                    @Override
+                    public void dragFinished(DragSourceEvent arg0)
+                    {
+
+                    }
+
+                    @Override
+                    public void dragSetData(DragSourceEvent e)
+                    {
+                        // get the selection
+                        TreeItem[] items = treeViewer.getTree().getSelection();
+                        FileEntry[] entries = new FileEntry[items.length];
+
+                        for (int i = 0; i < items.length; i++)
+                        {
+                            Object data = items[i].getData();
+                            if (data instanceof FileEntry)
+                            {
+                                entries[i] = ((FileEntry) data);
+                            }
+                        }
+
+                        if (FileEntryTransfer.getInstance().isSupportedType(e.dataType))
+                        {
+                            e.data = entries;
+                        } else if (PluginTransfer.getInstance().isSupportedType(e.dataType))
+                        {
+                            byte[] data = FileEntryTransfer.getInstance().toByteArray(entries);
+                            e.data = new PluginTransferData(DRAGACTIONID, data);
+                        }
+                    }
+                });
+
+        // setup drop listener
+        treeViewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, new Transfer[] { FileTransfer.getInstance() }, new ViewerDropAdapter(treeViewer)
+        {
+            @Override
+            public boolean performDrop(Object data)
+            {
+                // get the item on which we dropped the item(s)
+                FileEntry target = (FileEntry) getCurrentTarget();
+
+                // in case we drop at the same level as root
+                if (target == null)
+                {
+                    return false;
+                }
+
+                // if the target is not a directory, we get the parent directory
+                if (target.isDirectory() == false)
+                {
+                    target = target.getParent();
+                }
+
+                if (target == null)
+                {
+                    return false;
+                }
+
+                // get the list of files to drop
+                String[] files = (String[]) data;
+
+                // do the drop
+                pushFiles(files, target);
+
+                // we need to finish with a refresh
+                refresh(target);
+
+                return true;
+            }
+
+            @Override
+            public boolean validateDrop(Object target, int operation, TransferData transferType)
+            {
+                if (target == null)
+                {
+                    return false;
+                }
+
+                // convert to the real item
+                FileEntry targetEntry = (FileEntry) target;
+
+                // if the target is not a directory, we get the parent directory
+                if (targetEntry.isDirectory() == false)
+                {
+                    target = targetEntry.getParent();
+                }
+
+                if (target == null)
+                {
+                    return false;
+                }
+
+                return true;
+            }
+        });
+
+        return tree;
+    }
+
+    public void setToolItems(ToolItem push, ToolItem pull, ToolItem start)
+    {
+        pushToolItem = push;
+        pullToolItem = pull;
+        emulStartToolItem = start;
+    }
+
+    public void setActions(MenuManager pSubMenu, Action pActionPush, Action pActionPull, Action pActionRefresh, Action pActionRename, Action pActionProperty,
+            Action pActionDelete)
+    {
+        this.subMenu = pSubMenu;
+        this.actionPush = pActionPush;
+        this.actionPull = pActionPull;
+        this.actionRefresh = pActionRefresh;
+        this.actionRename = pActionRename;
+        this.actionProperty = pActionProperty;
+        this.actionDelete = pActionDelete;
+        setActionEnabled();
+    }
+
+    @Override
+    protected void postCreation()
+    {
+        ConnectionPlugin.getDefault().addSelectionListener(this);
+        SmartDevelopmentBridge sdbBridge = SmartDevelopmentBridge.getBridge();
+        SmartDevelopmentBridge.addDebugBridgeChangeListener(this);
+        SmartDevelopmentBridge.addDeviceChangeListener(this);
+
+        IDevice[] devices = null;
+        if (sdbBridge != null)
+        {
+            devices = sdbBridge.getDevices();
+        }
+        if (devices != null && devices.length != 0)
+        {
+            for (IDevice device : devices)
+            {
+                this.deviceConnected(device);
+            }
+        }
+    }
+
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus()
+    {
+        treeViewer.getTree().setFocus();
+    }
+
+    /**
+     * Pull the current selection on the local drive. This method displays a
+     * dialog box to let the user select where to store the file(s) and
+     * folder(s).
+     */
+    public void pullSelection()
+    {
+        DirectoryDialog dlg = new DirectoryDialog(parent.getShell(), SWT.SAVE);
+
+        setDialog(dlg, "Pull the selected content");
+
+        String directoryName = dlg.open();
+
+        if (directoryName != null)
+        {
+            pullSelection(treeViewer.getTree().getSelection(), directoryName);
+        }
+    }
+
+    /**
+     * Push new file(s) and folder(s) into the current selection. Current
+     * selection must be single item. If the current selection is not a
+     * directory, the ` directory is used. This method displays a dialog to let
+     * the user choose file to push to the device.
+     */
+    public void pushIntoSelection()
+    {
+        doActionForEntry(new IActionForEntry()
+        {
+            @Override
+            public void doAction()
+            {
+                FileEntry entry = getSingleFileEntry();
+
+                FileDialog dlg = new FileDialog(parent.getShell(), SWT.OPEN);
+
+                setDialog(dlg, "Push the Files");
+
+                String[] fileName = new String[1];
+                fileName[0] = dlg.open();
+
+                if (fileName[0] != null)
+                {
+                    // we need to figure out the remote path based on the
+                    // current selection type.
+                    FileEntry refreshFileEntry;
+
+                    if (entry.isDirectory() || entry.isRoot())
+                    {
+                        refreshFileEntry = entry;
+                    } else
+                    {
+                        refreshFileEntry = entry.getParent();
+                    }
+
+                    pushFiles(fileName, refreshFileEntry);
+                    refresh(refreshFileEntry);
+                }
+            }
+
+            @Override
+            public boolean doCheckEnable()
+            {
+                return isSingleEntry() && actionPush.isEnabled();
+            }
+        });
+    }
+
+    // only for FileDialog and DirectoryDialog
+    private void setDialog(Dialog dialog, String text)
+    {
+        dialog.setText(text);
+
+        String defaultPath = defaultSave;
+        if (defaultPath == null)
+        {
+            defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
+        }
+
+        if (dialog instanceof FileDialog)
+        {
+            FileDialog dlg = (FileDialog) dialog;
+            dlg.setFilterPath(defaultPath);
+            defaultSave = dlg.getFilterPath();
+        } else if (dialog instanceof DirectoryDialog)
+        {
+            DirectoryDialog dlg = (DirectoryDialog) dialog;
+            dlg.setFilterPath(defaultPath);
+            defaultSave = dlg.getFilterPath();
+        }
+    }
+
+    public void addNewFileSelection()
+    {
+        doActionForEntry(new IActionForEntry()
+        {
+            @Override
+            public void doAction()
+            {
+
+                FileEntry entry = getSingleFileEntry();
+
+                String name = getNameFromInputDialog("New File Resource", "New File Name: ", entry, "");
+
+                if (name == null)
+                {
+                    return;
+                }
+
+                String fullPath = FilenameUtil.addDoubleQuote(entry.getFullEscapedPath() + "/" + name);
+                String command = String.format("touch %s; echo $?", fullPath);
+                try
+                {
+                    currentDevice.executeShellCommand(command, new MultiLineReceiver()
+                    {
+
+                        @Override
+                        public void processNewLines(String[] lines)
+                        {
+                            sayError(lines, "add_file_error", "A file failed to be added");
+                        }
+                    });
+                } catch (IOException e)
+                {
+                    Logger.error("failed to add new file", e);
+                    throw new RuntimeException(e);
+                }
+                refresh(entry);
+            }
+
+            @Override
+            public boolean doCheckEnable()
+            {
+                return isSingleEntry();
+            }
+        });
+    }
+
+    public void addNewFolderSelection()
+    {
+        doActionForEntry(new IActionForEntry()
+        {
+            @Override
+            public void doAction()
+            {
+
+                FileEntry entry = getSingleFileEntry();
+
+                String name = getNameFromInputDialog("New Folder Resource", "New Folder Name: ", entry, "");
+                if (name == null)
+                {
+                    return;
+                }
+
+                // create the mkdir command
+                String fullPath = FilenameUtil.addDoubleQuote(entry.getFullEscapedPath() + "/" + name);
+                String command = String.format("mkdir %s; echo $?", fullPath);
+                try
+                {
+                    currentDevice.executeShellCommand(command, new MultiLineReceiver()
+                    {
+                        @Override
+                        public void processNewLines(String[] lines)
+                        {
+                            sayError(lines, "add_folder_error", "A folder failed to be added");
+                        }
+                    });
+                } catch (IOException e)
+                {
+                    Logger.error("failed to add new folder", e);
+                    throw new RuntimeException(e);
+                }
+                refresh(entry);
+            }
+
+            @Override
+            public boolean doCheckEnable()
+            {
+                return isSingleEntry();
+            }
+        });
+    }
+
+    // Get user input for adding new file or folder and rename
+    private String getNameFromInputDialog(String title, String message, FileEntry entry, String initValue)
+    {
+        boolean again;
+        InputDialog inputDialog;
+
+        do
+        {
+            again = false;
+            // open dialog to get input
+            inputDialog = new InputDialog(Display.getCurrent().getActiveShell(), title, message, initValue, new FileNameValidator());
+
+            if (inputDialog.open() != Window.OK)
+            {
+                return null;
+            }
+
+            String input = inputDialog.getValue();
+            // same entry is already exist..
+            if (findDuplicateFileEntry(input, entry))
+            {
+                again = true;
+            }
+
+        } while (again);
+
+        return FilenameUtil.getEscapedName(inputDialog.getValue());
+    }
+
+    public void renameSelection()
+    {
+        doActionForEntry(new IActionForEntry()
+        {
+            @Override
+            public void doAction()
+            {
+
+                FileEntry entry = getSingleFileEntry();
+
+                String name = getNameFromInputDialog("Rename Resource", "New name: ", entry.getParent(), entry.getName());
+
+                if (name == null)
+                {
+                    return;
+                }
+
+                String fullPath = entry.getFullEscapedPath();
+                int lastIndex = fullPath.lastIndexOf(PATH_SEPARATOR);
+                String newPath = fullPath.substring(0, lastIndex) + PATH_SEPARATOR + name;
+
+                // create the mv command
+                String command = String.format("mv %s %s; echo $?", FilenameUtil.addDoubleQuote(fullPath), FilenameUtil.addDoubleQuote(newPath));
+                try
+                {
+                    currentDevice.executeShellCommand(command, new MultiLineReceiver()
+                    {
+
+                        @Override
+                        public void processNewLines(String[] lines)
+                        {
+                            sayError(lines, "rename_error", "A selection failed to be renamed");
+                        }
+                    });
+                } catch (IOException e)
+                {
+                    Logger.error("failed to rename", e);
+                    throw new RuntimeException(e);
+                }
+                refresh(entry.getParent());
+            }
+
+            @Override
+            public boolean doCheckEnable()
+            {
+                return isSingleEntry() && actionRename.isEnabled();
+            }
+        });
+    }
+
+    public void deleteSelection()
+    {
+        doActionForEntry(new IActionForEntry()
+        {
+            @Override
+            public void doAction()
+            {
+                TreeItem[] items = treeViewer.getTree().getSelection();
+                for (TreeItem item : items)
+                {
+                    Object obj = item.getData();
+                    if (obj instanceof FileEntry)
+                    {
+                        FileEntry entry = (FileEntry) obj;
+                        int ret = FileDialogUtils.confirmDelete(entry.getName());
+                        if (ret == IDialogConstants.CANCEL_ID)
+                            continue;
+
+                        String command = null;
+                        // create the delete command
+                        if (entry.isDirectory())
+                        {
+                            command = String.format("rm -rf %s; echo $?", FilenameUtil.addDoubleQuote(entry.getFullEscapedPath()));
+                        } else
+                        {
+                            command = String.format("rm %s; echo $?", FilenameUtil.addDoubleQuote(entry.getFullEscapedPath()));
+                        }
+
+                        try
+                        {
+                            currentDevice.executeShellCommand(command, new MultiLineReceiver()
+                            {
+
+                                @Override
+                                public void processNewLines(String[] lines)
+                                {
+                                    sayError(lines, "delete_error", "A selection failed to be deleted");
+                                }
+                            });
+                            item.dispose();
+                        } catch (IOException e)
+                        {
+                            Logger.error("failed to delete", e);
+                            throw new RuntimeException(e);
+
+                        }
+                         refresh(entry.getParent());
+                         setActionEnabled();
+                    }
+                }
+            }
+
+            @Override
+            public boolean doCheckEnable()
+            {
+                return actionDelete.isEnabled();
+            }
+        });
+    }
+    
+    public void showPropertySelection(final IWorkbenchPartSite site)
+    {
+        doActionForEntry(new IActionForEntry()
+        {
+            @Override
+            public void doAction()
+            {
+                PropertyDialogAction pda = new PropertyDialogAction(site, treeViewer);
+                pda.run();
+            }
+
+            @Override
+            public boolean doCheckEnable()
+            {
+                return actionProperty.isEnabled();
+            }
+        });
+    }
+
+    private void sayError(String[] lines, String id, String message)
+    {
+        if (!lines[lines.length - 1].contains("0"))
+        {
+            StringBuilder sb = new StringBuilder();
+            for (String line : lines)
+            {
+                line = AnsicodeAdapter.getStripAnsiString(line);
+                sb.append(line);
+            }
+            Status status = new Status(IStatus.ERROR, id, 0, sb.toString(), null);
+            ErrorDialog.openError(Display.getCurrent().getActiveShell(), Messages.getString("FileDialogUtils.message.title"), message, status);
+        }
+    }
+
+    /**
+     * Sent when a new {@link SmartDevelopmentBridge} is started.
+     * <p/>
+     * This is sent from a non UI thread.
+     *
+     * @param bridge
+     *            the new {@link SmartDevelopmentBridge} object.
+     *
+     * @see IDebugBridgeChangeListener#serverChanged(SmartDevelopmentBridge)
+     */
+    @Override
+    public void bridgeChanged(final SmartDevelopmentBridge bridge)
+    {
+        final Tree tree = treeViewer.getTree();
+        if (tree.isDisposed() == false)
+        {
+            exec(new Runnable()
+            {
+                @Override
+                public void run()
+                {
+                    if (tree.isDisposed() == false)
+                    {
+                        // set up the data source.
+                        treeViewer.setInput(bridge);
+                    } else
+                    {
+                        // tree is disposed, we need to do something.
+                        // lets remove ourselves from the listener.
+                        SmartDevelopmentBridge.removeDebugBridgeChangeListener(ConnectionExplorerPanel.this);
+                        SmartDevelopmentBridge.removeDeviceChangeListener(ConnectionExplorerPanel.this);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Refresh an entry from a non ui thread.
+     *
+     * @param entry
+     *            the entry to refresh.
+     */
+    private void refresh(final FileEntry entry)
+    {
+        Display d = treeViewer.getTree().getDisplay();
+        d.asyncExec(new Runnable()
+        {
+            @Override
+            public void run()
+            {
+                treeViewer.refresh(entry, true);
+            }
+        });
+    }
+
+    public void refreshSelection()
+    {
+        if (treeViewer.getTree().getSelectionCount() == 0)
+        {
+            return;
+        }
+        refresh(getSingleFileEntry());
+    }
+
+    /**
+     * Pulls the selection from a device.
+     *
+     * @param items
+     *            the tree selection the remote file on the device
+     * @param localDirector
+     *            the local directory in which to save the files.
+     */
+    private void pullSelection(TreeItem[] items, final String localDirectory)
+    {
+        try
+        {
+            final SyncService sync = currentDevice.getSyncService();
+            if (sync != null)
+            {
+                // make a list of the FileEntry.
+                List<FileEntry> entries = new ArrayList<FileEntry>();
+                for (TreeItem item : items)
+                {
+                    Object data = item.getData();
+                    if (data instanceof FileEntry)
+                    {
+                        FileEntry entry = (FileEntry)data;
+                        if (!FilenameUtil.isVaildName(entry.getName()))
+                        {
+                            DialogUtil.openErrorDialog(entry.getName() + "\n" + 
+                                    ConnectionUIMessages.Explorer_Message_Invalid_Character
+                                    + FilenameUtil.getInvalidCharacters());
+                            continue;
+                        }
+                        entries.add((FileEntry) data);
+                    }
+                }
+                final FileEntry[] entryArray = entries.toArray(new FileEntry[entries.size()]);
+
+                // get a progress dialog
+                new ProgressMonitorDialog(parent.getShell()).run(true, true, new IRunnableWithProgress()
+                {
+                    @Override
+                    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
+                    {
+                        // create a monitor wrapper around the jface monitor
+                        SyncResult result = sync.pull(entryArray, localDirectory, (ISyncProgressMonitor) new SyncProgressMonitor(monitor,
+                                "Pulling file(s) from the device"));
+
+                        if (result.getCode() != SyncService.RESULT_OK)
+                        {
+                            String message = String.format("Failed to pull selection: %1$s", result.getMessage());
+                            console.println(message);
+                            DialogUtil.openErrorDialog(message);
+                        }
+                        sync.close();
+                    }
+                });
+            }
+        } catch (Exception e)
+        {
+            String message = "Failed to pull selection";
+            DialogUtil.openErrorDialog(message);
+            console.println(message);
+            console.println(e.getMessage());
+        }
+    }
+
+    /**
+     * Pushes several files and directory into a remote directory.
+     *
+     * @param localFiles
+     * @param remoteDirectory
+     */
+    private void pushFiles(final String[] localFiles, final FileEntry remoteDirectory)
+    {
+        final String[] files = getFilesToOverwrite(localFiles, remoteDirectory);
+        if (files == null || files.length == 0)
+            return;
+        try
+        {
+            final SyncService sync = currentDevice.getSyncService();
+            if (sync != null)
+            {
+                new ProgressMonitorDialog(parent.getShell()).run(true, true, new IRunnableWithProgress()
+                {
+                    @Override
+                    public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
+                    {
+                        SyncResult result = sync.push(files, remoteDirectory, (ISyncProgressMonitor) new SyncProgressMonitor(monitor,
+                                "Pushing file(s) to the device"));
+                        if (result.getCode() != SyncService.RESULT_OK)
+                        {
+                            String message = String.format("Failed to push the items: %1$s", result.getMessage());
+                            console.println(message);
+                            DialogUtil.openErrorDialog(message);
+                        }
+                        sync.close();
+                    }
+                });
+            }
+        } catch (Exception e)
+        {
+            String message = "Failed to push the items";
+            DialogUtil.openErrorDialog(message);
+            console.println(message);
+            console.println(e.getMessage());
+        }
+    }
+
+    private String[] getFilesToOverwrite(String[] src, FileEntry des)
+    {
+        FileEntry[] children = des.getFileListingService().getChildren(des, false, null);
+
+        List<String> listToOverwrite = new ArrayList<String>();
+        boolean yesAll = false;
+
+        for (String source : src)
+        {
+            File f = new File(source);
+            boolean bFind = false;
+            for (FileEntry entry : children)
+            {
+                if (entry.getName().equals(f.getName()))
+                {
+                    bFind = true;
+                    break;
+                }
+            }
+
+            if (bFind)
+            {
+                if (!yesAll)
+                {
+                    int ret;
+                    if (src.length == 1)
+                    {
+                        ret = FileDialogUtils.allowFileOverwrite(f.getName());
+                        if( ret == IDialogConstants.CANCEL_ID)
+                            break;
+                    } else
+                    {
+                        ret = FileDialogUtils.checkOverwrite(f.getName());
+                        switch (ret)
+                        {
+                        case IDialogConstants.CANCEL_ID:
+                            return null;
+                        case IDialogConstants.NO_ID:
+                            continue;
+                        case IDialogConstants.YES_TO_ALL_ID:
+                            yesAll = true;
+                        case IDialogConstants.YES_ID:
+                            break;
+                        default:
+                            break;
+                        }
+                    }
+                }
+            }
+            listToOverwrite.add(source);
+        }
+        return listToOverwrite.toArray(new String[0]);
+    }
+
+    private boolean findDuplicateFileEntry(String src, FileEntry des)
+    {
+        FileEntry[] children = des.getFileListingService().getChildren(des, false, null);
+
+        for (FileEntry entry : children)
+        {
+            File f = new File(src);
+
+            if (entry.getName().equals(f.getName()))
+            {
+                FileDialogUtils.notifyDuplication((f.getName()));
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 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.
+     *
+     * @see IDeviceChangeListener#deviceConnected(IDevice)
+     */
+    @Override
+    public void deviceConnected(IDevice device)
+    {
+        if (device.isOffline())
+        {
+            return;
+        }
+        devicesList.add(device);
+        ToolsInstall.installPackages(device);
+        execRefresh();
+    }
+
+    @Override
+    public void deviceDisconnected(IDevice device)
+    {
+        devicesList.remove(device);
+        execRefresh();
+    }
+
+    @Override
+    public void deviceChanged(IDevice device, int changeMask)
+    {
+        if (changeMask == 1)
+        {
+            deviceConnected(device);
+        }
+    }
+
+    private void execRefresh()
+    {
+        exec(new Runnable()
+        {
+            @Override
+            public void run()
+            {
+                if (treeViewer.getTree().isDisposed() == false)
+                {
+                    // refresh all
+                    treeViewer.refresh();
+
+                    // notify the listener of a possible selection change.
+                    notifyListeners();
+                } else
+                {
+                    // tree is disposed, we need to do something.
+                    // lets remove ourselves from the listener.
+                    SmartDevelopmentBridge.removeDebugBridgeChangeListener(ConnectionExplorerPanel.this);
+                    SmartDevelopmentBridge.removeDeviceChangeListener(ConnectionExplorerPanel.this);
+                }
+            }
+        });
+    }
+
+    public List<IDevice> getDeviceList()
+    {
+        return devicesList;
+    }
+
+    private void exec(Runnable runnable)
+    {
+        Tree tree = treeViewer.getTree();
+
+        if (tree.isDisposed() == false)
+        {
+            try
+            {
+                Display display = tree.getDisplay();
+                display.asyncExec(runnable);
+            } catch (SWTException e)
+            {
+                // tree is disposed, we need to do something. lets remove
+                // ourselves from the listener.
+                SmartDevelopmentBridge.removeDebugBridgeChangeListener(ConnectionExplorerPanel.this);
+                SmartDevelopmentBridge.removeDeviceChangeListener(ConnectionExplorerPanel.this);
+            }
+        }
+    }
+
+    private void notifyListeners()
+    {
+        Tree tree = treeViewer.getTree();
+        FileEntry entry = null;
+        if (tree.getSelectionCount() > 0)
+            entry = getSingleFileEntry();
+
+        if (entry != null)
+        {
+            currentDevice = entry.getFileListingService().getDevice();
+        } else
+        {
+            IDevice[] devices = SmartDevelopmentBridge.getBridge().getDevices();
+            if (devices.length != 0)
+            {
+                currentDevice = devices[0];
+                entry = devices[0].getFileListingService().getRoot();
+                for (TreeItem item : tree.getItems())
+                {
+                    if (item.getText().equals(entry.getName()))
+                    {
+                        tree.setSelection(item);
+                    }
+                }
+            } else
+                currentDevice = null;
+        }
+        ConnectionPlugin.getDefault().setCurrentDevice(currentDevice);
+        ConnectionPlugin.getDefault().notifySelectionListeners(entry);
+        setActionEnabled();
+
+    }
+
+    public TreeViewer getTreeViewer()
+    {
+        return treeViewer;
+    }
+
+    class FileNameValidator implements IInputValidator
+    {
+        @Override
+        public String isValid(String fileName)
+        {
+            int os = TizenPlatformConstants.OS;
+            int validCheck = FilenameUtil.isVaildName(fileName, os);
+            if (validCheck != FilenameUtil.IS_VALID_NAME)
+            {
+                switch(validCheck)
+                {
+                    case FilenameUtil.HAS_INVALID_CHARACTER:
+                        return ConnectionUIMessages.Explorer_Message_Invalid_Character + FilenameUtil.getInvalidCharacters(os);
+                    case FilenameUtil.HAS_NO_NAME:
+                        return "";
+                    default:
+                        break;
+                }
+            }
+            return null;
+        }
+    }
+
+    public int getActionState()
+    {
+        //sub, push, pull, refresh, rename, delete, property
+        int length = treeViewer.getTree().getSelectionCount();
+
+        int state = 0x0000000;
+        
+        if (length == 1)
+        {
+            FileEntry entry = getSingleFileEntry();
+            if (entry.isRoot())
+            {
+                state = STATE_SUB | STATE_PUSH| STATE_PULL | STATE_REFRESH | STATE_PROPERTY;
+            } else if (!entry.isDirectory())
+            {
+                state = STATE_PULL | STATE_REFRESH | STATE_RENAME | STATE_DELETE | STATE_PROPERTY;
+            } else
+            {
+                state = STATE_SUB | STATE_PUSH | STATE_PULL | STATE_REFRESH | STATE_RENAME | STATE_DELETE | STATE_PROPERTY;
+            }
+        } else if (length > 1)
+        {
+            state = STATE_PULL | STATE_DELETE;
+        }
+
+        return state;
+    }
+
+    private boolean getEnabled(int mode, int state)
+    {
+        int result = (mode & state);
+        return result != 0 ? true : false;
+    }
+
+    private void setActionEnabled()
+    {
+        int mode = getActionState();
+        subMenu.setVisible(getEnabled(mode, STATE_SUB));
+
+        boolean bPush = getEnabled(mode, STATE_PUSH);
+        actionPush.setEnabled(bPush);
+        pushToolItem.setEnabled(bPush);
+
+        boolean bPull = getEnabled(mode, STATE_PULL);
+        actionPull.setEnabled(bPull);
+        pullToolItem.setEnabled(bPull);
+
+        actionRename.setEnabled(getEnabled(mode, STATE_RENAME));
+        actionRefresh.setEnabled(getEnabled(mode, STATE_REFRESH));
+        actionDelete.setEnabled(getEnabled(mode, STATE_DELETE));
+        actionProperty.setEnabled(getEnabled(mode, STATE_PROPERTY));
+    }
+
+    private FileEntry getSingleFileEntry()
+    {
+        Tree tree = treeViewer.getTree();
+        if (tree.getSelectionCount() != 0)
+        {
+            TreeItem[] items = tree.getSelection();
+            return (FileEntry) items[0].getData();
+        } else
+            return null;
+    }
+
+    @Override
+    public void selectionChanged(final FileEntry selectedEntry)
+    {
+
+        if (selectedEntry == null)
+        {
+            return;
+        }
+
+        if (!selectedEntry.isRoot())
+        {
+            return;
+        }
+
+        final Tree tree = treeViewer.getTree();
+        exec(new Runnable()
+        {
+            @Override
+            public void run()
+            {
+                if (tree.isDisposed() == false)
+                {
+                    for (TreeItem item : tree.getItems())
+                    {
+                        if (item.getText().equals(selectedEntry.getName()))
+                            tree.setSelection(item);
+                    }
+                } else
+                {
+                    // tree is disposed, we need to do something.
+                    // lets remove ourselves from the listener.
+                    ConnectionPlugin.getDefault().removeSelectionListener(ConnectionExplorerPanel.this);
+                }
+            }
+        });
+    }
+    
+    private boolean isSingleEntry()
+    {
+        Tree tree = treeViewer.getTree();
+        if (tree.getSelectionCount() == 1)
+        {
+            return true;
+        } else
+        {
+            return false;
+        }
+    }
+
+    public void doActionForEntry(IActionForEntry action)
+    {
+        if (action.doCheckEnable())
+        {
+            action.doAction();
+        }
+    }
+
+    private interface IActionForEntry
+    {
+        public boolean  doCheckEnable();
+
+        public void doAction();
+    }
 }
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 28a1661..f603e24
@@ -52,80 +52,4 @@ public class Messages {
                        return '!' + key + '!';\r
                }\r
        }\r
-       private static String messageBind(String message, Object[] args, String argZero, String argOne) {\r
-               int length = message.length();\r
-               //estimate correct size of string buffer to avoid growth\r
-               int bufLen = length + (args.length * 5);\r
-               if (argZero != null)\r
-                       bufLen += argZero.length() - 3;\r
-               if (argOne != null)\r
-                       bufLen += argOne.length() - 3;\r
-               StringBuffer buffer = new StringBuffer(bufLen < 0 ? 0 : bufLen);\r
-               for (int i = 0; i < length; i++) {\r
-                       char c = message.charAt(i);\r
-                       switch (c) {\r
-                               case '{' :\r
-                                       int index = message.indexOf('}', i);\r
-                                       // if we don't have a matching closing brace then...\r
-                                       if (index == -1) {\r
-                                               buffer.append(c);\r
-                                               break;\r
-                                       }\r
-                                       i++;\r
-                                       if (i >= length) {\r
-                                               buffer.append(c);\r
-                                               break;\r
-                                       }\r
-                                       // look for a substitution\r
-                                       int number = -1;\r
-                                       try {\r
-                                               number = Integer.parseInt(message.substring(i, index));\r
-                                       } catch (NumberFormatException e) {\r
-                                               throw (IllegalArgumentException) new IllegalArgumentException().initCause(e);\r
-                                       }\r
-                                       if (number == 0 && argZero != null)\r
-                                               buffer.append(argZero);\r
-                                       else if (number == 1 && argOne != null)\r
-                                               buffer.append(argOne);\r
-                                       else {\r
-                                               if (number >= args.length || number < 0) {\r
-                                                       buffer.append("<missing argument>"); //$NON-NLS-1$\r
-                                                       i = index;\r
-                                                       break;\r
-                                               }\r
-                                               buffer.append(args[number]);\r
-                                       }\r
-                                       i = index;\r
-                                       break;\r
-                               case '\'' :\r
-                                       // if a single quote is the last char on the line then skip it\r
-                                       int nextIndex = i + 1;\r
-                                       if (nextIndex >= length) {\r
-                                               buffer.append(c);\r
-                                               break;\r
-                                       }\r
-                                       char next = message.charAt(nextIndex);\r
-                                       // if the next char is another single quote then write out one\r
-                                       if (next == '\'') {\r
-                                               i++;\r
-                                               buffer.append(c);\r
-                                               break;\r
-                                       }\r
-                                       // otherwise we want to read until we get to the next single quote\r
-                                       index = message.indexOf('\'', nextIndex);\r
-                                       // if there are no more in the string, then skip it\r
-                                       if (index == -1) {\r
-                                               buffer.append(c);\r
-                                               break;\r
-                                       }\r
-                                       // otherwise write out the chars inside the quotes\r
-                                       buffer.append(message.substring(nextIndex, index));\r
-                                       i = index;\r
-                                       break;\r
-                               default :\r
-                                       buffer.append(c);\r
-                       }\r
-               }\r
-               return buffer.toString();\r
-       }\r
 }\r
index 3d54a9c..28acc15 100644 (file)
@@ -1,9 +1,8 @@
-\r
-FileDialogUtils.overrite.title=File Exists\r
-FileDialogUtils.overrite.message=The file {0} already exists. Are you going to overwrite it?\r
-FileDialogUtils.delete.title=File Delete\r
-FileDialogUtils.delete.message=Are you going to delete {0}?\r
-FileDialogUtils.tabName.title=Invalid Name\r
-FileDialogUtils.tabName.message= "{0}" is already exist!\nPlease fill in the TabName with another.\r
+FileDialogUtils.message.title=Message\r
+FileDialogUtils.overwrite.message=The {0} file already exists. Do you want to overwrite it?\r
+FileDialogUtils.duplicate.message=Existing file\r
+FileDialogUtils.delete.message=Are you sure you want to delete the {0} file?\r
+FileDialogUtils.tabName.message= The tab name already exists. Enter a different name.\r
 FileDialogUtils.update.title=Tizen SDK\r
-FileDialogUtils.update.message= Updates are available for Tizen SDK. Do you want to install them?\r
+FileDialogUtils.update.message= Tizen SDK updates are available. Do you want to install them now?\r
+ConnectionExplorer.tree.header=Files
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 2d6ccd3..13cb202
@@ -1,30 +1,32 @@
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact:
-* Hoon Kang <h245.kang@samsung.com>
-* Hyunsik Noh <hyunsik.noh@samsung.com>
-*
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hoon Kang <h245.kang@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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
-*
-*/
+ * 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.common.connection.log;
 
+import static org.tizen.common.util.StringUtil.isEmpty;
+
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
@@ -50,268 +52,314 @@ import org.tizen.sdblib.SmartDevelopmentBridge;
 /**
  * Small dialog box to open new logtab with some options.
  */
-public class AddViewDialog extends Dialog {
-
-       private static final int DLG_WIDTH = 400;
-       private static final int DLG_HEIGHT = 300;
-
-       private Shell parent;
-
-       private Shell shell;
-
-       private String dialogName = null;
-
-       private boolean bOk = false;
-
-       private LogTab oldTab = null;
-
-       private static final String TEMPNAME = "LogTab-#";
-       private static int cnt = 0;
-
-       private String tabName = null;
-       private String device = null;
-       private String pidKeyword = null;
-       private String tagKeyword = null;
-       private String msgKeyword = null;
-
-       private Text tabNameText;
-       private Text tagText;
-       private Text pidText;
-       private Text msgText;
-       private Button okButton;
-
-       public AddViewDialog(Shell pParent) {
-               super(pParent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
-       }
-
-       public AddViewDialog(Shell pParent, String deviceName) {
-               super(pParent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
-               device = deviceName;
-               dialogName = "Add LogTab";
-       }
-
-       public AddViewDialog(Shell pParent, LogTab tab) {
-               super(pParent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
-               if (tab != null) {
-                       dialogName = "Edit LogTab";
-                       tabName = tab.getFilterName();
-                       if (tab.getFilterDeviceName() == null)
-                               return;
-                       device = tab.getFilterDeviceName();
-
-                       pidKeyword = tab.getPidFilter();
-                       tagKeyword = tab.getTagFilter();
-                       msgKeyword = tab.getMsgFilter();
-
-                       oldTab = tab;
-               }
-       }
-
-       /**
-        * Opens the dialog. The method will return when the user closes the dialog
-        * somehow.
-        *
-        * @return true if ok was pressed, false if cancelled.
-        */
-       public boolean open() {
-               createUI();
-
-               if (parent == null || shell == null) {
-                       return false;
-               }
-
-               shell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
-               Rectangle r = parent.getBounds();
-               // get the center new top left.
-               int cx = r.x + r.width / 2;
-               int x = cx - DLG_WIDTH / 2;
-               int cy = r.y + r.height / 2;
-               int y = cy - DLG_HEIGHT / 2;
-               shell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
-
-               shell.open();
-
-               Display display = parent.getDisplay();
-               while (!shell.isDisposed()) {
-                       if (!display.readAndDispatch())
-                               display.sleep();
-               }
-
-               return bOk;
-       }
-
-       private void createUI() {
-               parent = getParent();
-               shell = new Shell(parent, getStyle());
-               shell.setText(dialogName);
-
-               shell.setLayout(new GridLayout(1, false));
-
-               shell.addListener(SWT.Close, new Listener() {
-                       @Override
-                       public void handleEvent(Event event) {
-                       }
-               });
-
-               Group top = new Group(shell, SWT.SHADOW_IN);
-               top.setText("LogTab");
-               top.setLayoutData(new GridData(GridData.FILL_BOTH));
-               top.setLayout(new GridLayout(2, false));
-
-               Label l = new Label(top, SWT.NONE);
-               l.setText("Name : ");
-
-               tabNameText = new Text(top, SWT.SINGLE | SWT.BORDER);
-               if (tabName != null)
-                       tabNameText.setText(tabName);
-               tabNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-               l = new Label(top, SWT.NONE);
-               l.setText("Device : ");
-
-               final Combo dCombo = new Combo(top, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.CENTER);
-               GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-
-               dCombo.setLayoutData(gd);
-               IDevice[] devices = SmartDevelopmentBridge.getBridge().getDevices();
-
-               if (devices.length != 0) {
-                       for (IDevice d : devices) {
-                               if (d.isOnline())
-                                       dCombo.add(d.getSerialNumber());
-                       }
-
-                       if (device != null) {
-                               for (int i = 0; i < devices.length; i++) {
-                                       if (device.equals(devices[i].getSerialNumber())) {
-                                               dCombo.select(i);
-                                               break;
-                                       }
-                               }
-                       } else {
-                               dCombo.select(0);
-                               device = dCombo.getItem(0);
-                       }
-               }
-
-               Group mid = new Group(shell, SWT.SHADOW_IN);
-               mid.setText("Search Keywords");
-               mid.setLayoutData(new GridData(GridData.FILL_BOTH));
-               mid.setLayout(new GridLayout(2, false));
-
-               l = new Label(mid, SWT.NONE);
-               l.setText("Tag : ");
-
-               tagText = new Text(mid, SWT.SINGLE | SWT.BORDER);
-               if (tagKeyword != null)
-                       tagText.setText(tagKeyword);
-               tagText.setMessage("Separated by a space/comma");
-               tagText.setToolTipText("Search Tag Keywords are separated by a space as well as a comma");
-               tagText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-               l = new Label(mid, SWT.NONE);
-               l.setText("Pid : ");
-
-               pidText = new Text(mid, SWT.SINGLE | SWT.BORDER);
-               if (pidKeyword != null)
-                       pidText.setText(pidKeyword);
-               pidText.setMessage("Separated by a space/comma");
-               pidText.setToolTipText("Search Pid Keywords are separated by a space as well as a comma");
-               pidText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-               l = new Label(mid, SWT.NONE);
-               l.setText("Message : ");
-
-               msgText = new Text(mid, SWT.SINGLE | SWT.BORDER);
-               if (msgKeyword != null)
-                       msgText.setText(msgKeyword);
-               msgText.setMessage("Separated by a space/comma");
-               msgText.setToolTipText("Search Message Keywords are separated by a space as well as a comma");
-               msgText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-               // bottom part with the ok/cancel
-               Composite bottomComp = new Composite(shell, SWT.NONE);
-               bottomComp
-                               .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
-               bottomComp.setLayout(new GridLayout(2, true));
-
-               okButton = new Button(bottomComp, SWT.NONE);
-               okButton.setText("OK");
-               okButton.addSelectionListener(new SelectionAdapter() {
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               String newName = tabNameText.getText();
-                               for (LogTab tab : LogPanel.tabs) {
-                                       if (tab.getFilterName().equals(newName)) {
-                                               if (oldTab != null && oldTab == tab)
-                                                       continue;
-                                               int ret = FileDialogUtils.getInstance().checkTabName(newName);
-                                               if (ret == IDialogConstants.OK_ID)
-                                                       return;
-                                       }
-                               }
-
-                               bOk = true;
-
-                               if (tabNameText.getText().length() != 0)
-                                       tabName = tabNameText.getText();
-                               else
-                                       tabName = TEMPNAME + cnt++;
-
-                               if (tagText.getText().length() != 0)
-                                       tagKeyword = tagText.getText();
-                               else
-                                       tagKeyword = null;
-
-                               if (pidText.getText().length() != 0)
-                                       pidKeyword = pidText.getText();
-                               else
-                                       pidKeyword = null;
-
-                               if (msgText.getText().length() != 0)
-                                       msgKeyword = msgText.getText();
-                               else
-                                       msgKeyword = null;
-
-                               device = dCombo.getItem(dCombo.getSelectionIndex());
-
-                               shell.close();
-                               }
-               });
-               shell.setDefaultButton(okButton);
-
-               Button cancelButton = new Button(bottomComp, SWT.NONE);
-               cancelButton.setText("Cancel");
-               cancelButton.addSelectionListener(new SelectionAdapter() {
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               shell.close();
-                       }
-               });
-
-       }
-
-       public String getName() {
-               return tabName;
-       }
-
-       public String getDevice() {
-               return device;
-       }
-
-       public String getPidKeyword() {
-               return pidKeyword;
-       }
-
-       public String getTagKeyword() {
-               return tagKeyword;
-       }
-
-       public String getMsgKeyword() {
-               return msgKeyword;
-       }
-
-       public void setName(String name) {
-               this.tabName = name;
-       }
+public class AddViewDialog extends Dialog
+{
+
+    private static final int DLG_WIDTH = 400;
+    private static final int DLG_HEIGHT = 300;
+
+    private Shell parent;
+
+    private Shell shell;
+
+    private String dialogName = null;
+
+    private boolean bOk = false;
+
+    private LogTab oldTab = null;
+
+    private static final String TEMPNAME = "LogTab-#";
+    private static int cnt = 0;
+
+    private String tabName = null;
+    private String device = null;
+    private String pidKeyword = null;
+    private String tagKeyword = null;
+    private String msgKeyword = null;
+
+    private Text tabNameText;
+    private Text tagText;
+    private Text pidText;
+    private Text msgText;
+    private Button okButton;
+
+    public AddViewDialog(Shell pParent)
+    {
+        super(pParent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+    }
+
+    public AddViewDialog(Shell pParent, String deviceName)
+    {
+        super(pParent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+        device = deviceName;
+        dialogName = "Add LogTab";
+    }
+
+    public AddViewDialog(Shell pParent, LogTab tab)
+    {
+        super(pParent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+        if (tab != null)
+        {
+            dialogName = "Edit LogTab";
+            tabName = tab.getLogTabName();
+            if (tab.getDeviceSerialNumber() == null)
+            {
+                return;
+            }
+            device = tab.getDeviceSerialNumber();
+
+            pidKeyword = tab.getPidFilter();
+            tagKeyword = tab.getTagFilter();
+            msgKeyword = tab.getMsgFilter();
+
+            oldTab = tab;
+        }
+    }
+
+    /**
+     * Opens the dialog. The method will return when the user closes the dialog
+     * somehow.
+     *
+     * @return true if ok was pressed, false if cancelled.
+     */
+    public boolean open()
+    {
+        createUI();
+
+        if (parent == null || shell == null)
+        {
+            return false;
+        }
+
+        shell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
+        Rectangle r = parent.getBounds();
+        // get the center new top left.
+        int cx = r.x + r.width / 2;
+        int x = cx - DLG_WIDTH / 2;
+        int cy = r.y + r.height / 2;
+        int y = cy - DLG_HEIGHT / 2;
+        shell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
+
+        shell.open();
+
+        Display display = parent.getDisplay();
+        while (!shell.isDisposed())
+        {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+
+        return bOk;
+    }
+
+    private void createUI()
+    {
+        parent = getParent();
+        shell = new Shell(parent, getStyle());
+        shell.setText(dialogName);
+
+        shell.setLayout(new GridLayout(1, false));
+
+        shell.addListener(SWT.Close, new Listener()
+        {
+            @Override
+            public void handleEvent(Event event)
+            {
+            }
+        });
+
+        Group top = new Group(shell, SWT.SHADOW_IN);
+        top.setText("LogTab");
+        top.setLayoutData(new GridData(GridData.FILL_BOTH));
+        top.setLayout(new GridLayout(2, false));
+
+        Label l = new Label(top, SWT.NONE);
+        l.setText("Name:");
+
+        tabNameText = new Text(top, SWT.SINGLE | SWT.BORDER);
+        if (tabName != null)
+            tabNameText.setText(tabName);
+        tabNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        l = new Label(top, SWT.NONE);
+        l.setText("Device:");
+
+        final Combo dCombo = new Combo(top, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.CENTER);
+        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+
+        dCombo.setLayoutData(gd);
+        IDevice[] devices = SmartDevelopmentBridge.getBridge().getDevices();
+
+        if (devices.length != 0)
+        {
+            for (IDevice d : devices)
+            {
+                if (d.isOnline())
+                    dCombo.add(d.getSerialNumber());
+            }
+
+            if (device != null)
+            {
+                for (int i = 0; i < devices.length; i++)
+                {
+                    if (device.equals(devices[i].getSerialNumber()))
+                    {
+                        dCombo.select(i);
+                        break;
+                    }
+                }
+            } else
+            {
+                dCombo.select(0);
+                device = dCombo.getItem(0);
+            }
+        }
+
+        Group mid = new Group(shell, SWT.SHADOW_IN);
+        mid.setText("Search keywords");
+        mid.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mid.setLayout(new GridLayout(2, false));
+
+        l = new Label(mid, SWT.NONE);
+        l.setText("Tag:");
+
+        tagText = new Text(mid, SWT.SINGLE | SWT.BORDER);
+        if (tagKeyword != null)
+            tagText.setText(tagKeyword);
+        tagText.setMessage("Separated by a space and comma");
+        tagText.setToolTipText("Search Tag Keywords are separated by a space as well as a comma");
+        tagText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        l = new Label(mid, SWT.NONE);
+        l.setText("Pid:");
+
+        pidText = new Text(mid, SWT.SINGLE | SWT.BORDER);
+        if (pidKeyword != null)
+            pidText.setText(pidKeyword);
+        pidText.setMessage("Separated by a space and comma");
+        pidText.setToolTipText("Search Pid Keywords are separated by a space as well as a comma");
+        pidText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        l = new Label(mid, SWT.NONE);
+        l.setText("Message:");
+
+        msgText = new Text(mid, SWT.SINGLE | SWT.BORDER);
+        if (msgKeyword != null)
+            msgText.setText(msgKeyword);
+        msgText.setMessage("Separated by a space and comma");
+        msgText.setToolTipText("Search Message Keywords are separated by a space as well as a comma");
+        msgText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // bottom part with the ok/cancel
+        Composite bottomComp = new Composite(shell, SWT.NONE);
+        bottomComp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+        bottomComp.setLayout(new GridLayout(2, true));
+
+        okButton = new Button(bottomComp, SWT.NONE);
+        okButton.setText("OK");
+        okButton.addSelectionListener(new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e)
+            {
+                String newName = tabNameText.getText();
+                for (LogTab tab : LogPanel.logTabList)
+                {
+                    if (tab.getLogTabName().equals(newName))
+                    {
+                        if (oldTab != null && oldTab == tab)
+                            continue;
+                        int ret = FileDialogUtils.checkTabName(newName);
+                        if (ret == IDialogConstants.OK_ID)
+                            return;
+                    }
+                }
+
+                bOk = true;
+                
+                if ( isEmpty( tabNameText.getText() ) )
+                {
+                    tabName = TEMPNAME + cnt++;
+                }
+                else
+                {
+                    tabName = tabNameText.getText();
+                }
+
+                if ( isEmpty( tagText.getText() ) )
+                {
+                    tagKeyword = null;
+                }
+                else
+                {
+                    tagKeyword = tagText.getText();
+                }
+
+                if ( isEmpty( pidText.getText() ) )
+                {
+                    pidKeyword = null;
+                }
+                else
+                {
+                    pidKeyword = pidText.getText();
+                }
+
+                if ( isEmpty( msgText.getText() ) )
+                {
+                    msgKeyword = null;
+                }
+                else
+                {
+                    msgKeyword = msgText.getText();
+                }
+
+                device = dCombo.getItem(dCombo.getSelectionIndex());
+
+                shell.close();
+            }
+        });
+        shell.setDefaultButton(okButton);
+
+        Button cancelButton = new Button(bottomComp, SWT.NONE);
+        cancelButton.setText("Cancel");
+        cancelButton.addSelectionListener(new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e)
+            {
+                shell.close();
+            }
+        });
+
+    }
+
+    public String getName()
+    {
+        return tabName;
+    }
+
+    public String getDevice()
+    {
+        return device;
+    }
+
+    public String getPidKeyword()
+    {
+        return pidKeyword;
+    }
+
+    public String getTagKeyword()
+    {
+        return tagKeyword;
+    }
+
+    public String getMsgKeyword()
+    {
+        return msgKeyword;
+    }
+
+    public void setName(String name)
+    {
+        this.tabName = name;
+    }
 }
\ No newline at end of file
index 83910f9..b7be832 100644 (file)
@@ -17,6 +17,8 @@ package org.tizen.common.connection.log;
  */
 
 import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+import org.tizen.common.util.SWTUtil;
 
 public class LogColors {
     public Color infoColor;
@@ -24,4 +26,18 @@ public class LogColors {
     public Color errorColor;
     public Color warningColor;
     public Color verboseColor;
+
+    public LogColors(Display display)
+    {
+        infoColor = new Color(display, 66, 120, 157);
+        debugColor = new Color(display, 129, 89, 168);
+        errorColor = new Color(display, 188, 108, 119);
+        warningColor = new Color(display, 191, 106, 51);
+        verboseColor = new Color(display, 90, 90, 90);
+    }
+
+    public void dispose()
+    {
+        SWTUtil.tryDispose(infoColor, debugColor, errorColor, warningColor, verboseColor);
+    }
 }
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 12b45b6..2f9427d
@@ -1,28 +1,28 @@
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact:
-* Hoon Kang <h245.kang@samsung.com>
-* Hyunsik Noh <hyunsik.noh@samsung.com>
-*
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hoon Kang <h245.kang@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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
-*
-*/
+ * 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.common.connection.log;
 
 import java.io.File;
@@ -30,10 +30,13 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
 
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
 import org.eclipse.swt.dnd.Clipboard;
 import org.eclipse.swt.dnd.TextTransfer;
 import org.eclipse.swt.dnd.Transfer;
@@ -65,756 +68,916 @@ import org.tizen.common.connection.ddmuilib.FileDialogUtils;
 import org.tizen.common.connection.ddmuilib.ITableFocusListener;
 import org.tizen.common.connection.ddmuilib.ITableFocusListener.IFocusedTableActivator;
 import org.tizen.common.connection.ddmuilib.Panel;
+import org.tizen.common.connection.explorer.ConnectionExplorerLabelProvider;
 import org.tizen.common.util.DialogUtil;
 import org.tizen.common.util.NotificationType;
 import org.tizen.common.util.NotifierDialog;
+import org.tizen.common.util.SWTUtil;
 import org.tizen.sdblib.IDevice;
 import org.tizen.sdblib.Log.LogLevel;
 import org.tizen.sdblib.SmartDevelopmentBridge;
 import org.tizen.sdblib.SmartDevelopmentBridge.IDeviceChangeListener;
 
-public class LogPanel extends Panel implements IDeviceChangeListener {
-
-       public static final int ACTION_NOTHING = 0;
-       public static final int ACTION_DEVICE_TAB = 1;
-       public static final int ACTION_ADDITIONAL_TAB = 2;
-
-       public static ArrayList<LogTab> tabs = new ArrayList<LogTab>();
-
-       private String defaultLogSave;
-
-       private static int tabCnt = 0;
-
-       private Composite parent;
-       private TabFolder folders;
-       private Table table;
-
-       private Combo panelFilterIndex;
-       private Text panelFilterKeyword;
-
-       private final LogColors colors;
-
-       private LogTab currentTab;
-
-       private Action[] levelActions;
-       private Action addAction;
-       private Action removeAction;
-       private Action editAction;
-       private Action exportAction;
-       private Action clearAction;
-
-       private Control control;
-
-       /** message data, separated from content for multi line messages */
-       protected static class LogMessageInfo {
-               public LogLevel logLevel;
-               public String pidString;
-               public String tag;
-               public String time;
-       }
-
-       private ITableFocusListener globalListener;
-
-       /** message data, separated from content for multi line messages */
-       protected static class LogMessage {
-               public LogMessageInfo data;
-               public String msg;
-
-               @Override
-               public String toString() {
-                       return data.time + ": " + data.logLevel + "/" + data.tag + "(" + data.pidString + "): " + msg;
-               }
-       }
-
-       /**
-        * Create the log panel with some default parameters
-        *
-        * @param colors
-        *            The display color object
-        */
-       public LogPanel(LogColors pColors) {
-               colors = pColors;
-       }
-
-       public void setActions(Action[] levels, Action add, Action remove,
-                       Action edit, Action export, Action clear) {
-               levelActions = levels;
-               addAction = add;
-               removeAction = remove;
-               editAction = edit;
-               exportAction = export;
-               clearAction = clear;
-       }
-
-       /**
-        * Creates a control capable of displaying some information. This is called
-        * once, when the application is initializing, from the UI thread.
-        */
-       @Override
-       protected Control createControl(Composite p) {
-
-               parent = p;
-
-               // create the tab folder
-               folders = new TabFolder(parent, SWT.NONE);
-               folders.setLayoutData(new GridData(GridData.FILL_BOTH));
-               folders.addSelectionListener(new SelectionAdapter() {
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               selectLogTab();
-                       }
-               });
-
-               control = getTabControl(folders);
-               SmartDevelopmentBridge.addDeviceChangeListener(this);
-               //Create default device tab if device(s) is connectied
-               createDefaultTabs();
-               selectLogTab();
-               return null;
-       }
-
-       private void selectLogTab()
-       {
-               //1.get selected tabitem's logtab
-               //2.set previous logtab view filter and get selected logtab view filter
-               initViewFilter(getCurrentLogTab());
-               if (currentTab == null)
-                       return;
-               //remove all message and re-fill message into table from selected logtab msg buffer
-               currentTab.initTab();
-
-               //set icon selection from selected logtab object
-               currentTab.setLevelIcon(levelActions);
-
-               //Set action enabled state from selected tab(LotTab object)
-               if (currentTab.isDefault()) {
-                       setActionEnabled(LogPanel.ACTION_DEVICE_TAB);
-               } else {
-                       setActionEnabled(LogPanel.ACTION_ADDITIONAL_TAB);
-               }
-       }
-
-       /**
-        *
-        * Create the LogFilters with default devicesd
-        *
-        */
-       private void createDefaultTabs() {
-               SmartDevelopmentBridge sdbBridge = SmartDevelopmentBridge.getBridge();
-               IDevice[] devices = null;
-               if (sdbBridge != null) {
-                       devices = sdbBridge.getDevices();
-               }
-
-               if (devices != null) {
-                       for (IDevice device : devices) {
-                               if (device.isOffline())
-                                       continue;
-                               LogTab dTab = createDefaultTab(device, null);
-                               dTab.startLogTab();
-                       }
-               }
-       }
-
-       private LogTab createDefaultTab(IDevice device, String tabName) {
-               LogTab tab = createTab(device, null);
-               tab.setDefault();
-               setActionEnabled(LogPanel.ACTION_DEVICE_TAB);
-               return tab;
-       }
-
-       private LogTab createTab(IDevice device, String tabName) {
-
-               LogTab tab = null;
-               if (tabName == null)
-                       tab = new LogTab(device.getSerialNumber(), device, colors);
-               else
-                       tab = new LogTab(tabName, device, colors);
-
-               //
-               for (int i = 0; i < tabs.size(); i++) {
-                       LogTab oldTab = tabs.get(i);
-                       if (oldTab.getFilterName().equals(tab.getFilterName())) {
-                               oldTab.stopLogTab(true);
-                               tabs.remove(i);
-                               tabCnt--;
-                               oldTab.dispose();
-                               if (!tabs.isEmpty())
-                                       folders.setSelection(0);
-                       }
-               }
-
-               TabItem item = new TabItem(folders, SWT.NONE, tabCnt++);
-
-               item.setText(tab.getFilterName());
-               tab.setTable(table);
-               item.setControl(control);
-               tab.setTab(item);
-
-               folders.setSelection(item);
-               tabs.add(tab);
-
-               if (tab.isDefault()) {
-                       setActionEnabled(LogPanel.ACTION_DEVICE_TAB);
-               } else {
-                       setActionEnabled(LogPanel.ACTION_ADDITIONAL_TAB);
-               }
-               tab.setLevelIcon(levelActions);
-               return tab;
-       }
-
-       private void initViewFilter(LogTab tab)
-       {
-               if(currentTab != null)
-               {
-                       currentTab.setFilterIndexFromPanel(panelFilterIndex.getSelectionIndex());
-                       currentTab.setFilterKeywordFromPanel(panelFilterKeyword.getText());
-               }
-
-               currentTab = tab;
-
-               if(tab != null)
-               {
-                       panelFilterIndex.select(tab.getFilterIndexFromPanel());
-                       panelFilterKeyword.setText(tab.getFilterKeywordFromPanel());
-               }
-       }
-
-       private Control getTabControl(TabFolder tabFolder) {
-               // Create a composite and add four buttons to it
-
-               Composite composite = new Composite(tabFolder, SWT.NONE);
-               composite.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-               composite.setLayout(new GridLayout(1, false));
-
-               Composite mid = new Composite(composite, SWT.NONE);
-               mid.setLayoutData(new GridData(GridData.FILL_BOTH));
-               mid.setLayout(new FillLayout());
-
-               table = new Table(mid, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER | SWT.H_SCROLL);
-
-               table.setHeaderVisible(true);
-               table.setLinesVisible(true);
-
-               if (globalListener != null) {
-                       addTableToFocusListener(table);
-               }
-
-               ControlListener listener = null;
-               listener = new ControlListener() {
-                       @Override
-                       public void controlMoved(ControlEvent e) {
-
-                       }
-
-                       @Override
-                       public void controlResized(ControlEvent e) {
-                               Rectangle r = table.getClientArea();
-
-                               // get the size of all but the last column
-                               int total = table.getColumn(0).getWidth();
-                               total += table.getColumn(1).getWidth();
-                               total += table.getColumn(2).getWidth();
-                               total += table.getColumn(3).getWidth();
-//
-                               if (r.width > total) {
-                                       table.getColumn(4).setWidth(r.width - total);
-                               }
-                       }
-               };
-
-               table.addControlListener(listener);
-
-               // then its column
-               TableColumn col = createTableColumn(table, "Time", SWT.LEFT,
-                               "00-00 00:00:00.000");
-               col.addControlListener(listener);
-
-               col = createTableColumn(table, "Level", SWT.LEFT, "Verbose");
-               col.addControlListener(listener);
-
-               col = createTableColumn(table, "Pid", SWT.LEFT, "9999999");
-               col.addControlListener(listener);
-
-               col = createTableColumn(table, "Tag", SWT.LEFT, "ABCDEFGHIJK");
-               col.addControlListener(listener);
-
-               col = createTableColumn(table, "Message", SWT.LEFT,
-                               "abcdefghijklmnopqrstuvwxyz0123456789");
-//             col.setResizable(false);
-
-               Composite bottom = new Composite(composite, SWT.NONE);
-               bottom.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-               bottom.setLayout(new GridLayout(3, false));
-
-               panelFilterIndex = new Combo(bottom, SWT.READ_ONLY);
-               String[] comboItems = {"Pid", "Tag", "Message"};
-               panelFilterIndex.setItems(comboItems);
-               panelFilterIndex.select(2);
-               panelFilterIndex.setToolTipText(LogUIMessages.Log_Tooltip_View_Filter_Combo);
-               panelFilterIndex.addSelectionListener(new SelectionListener() {
-                     @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               if(currentTab != null)
-                                       {
-                                 int index = panelFilterIndex.getSelectionIndex();
-                                 if (panelFilterKeyword.getText() != null) {
-                                         currentTab.tableRefill(index, panelFilterKeyword.getText());
-                                 }
-                                       }
-                       }
-
-                       @Override
-                               public void widgetDefaultSelected(SelectionEvent e) {
-                       }
-                     });
-
-               panelFilterKeyword = new Text(bottom, SWT.SINGLE | SWT.BORDER);
-               panelFilterKeyword.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-               panelFilterKeyword.setMessage(LogUIMessages.Log_Message_View_Filter_Text);
-               panelFilterKeyword.addModifyListener(new ModifyListener() {
-
-                       @Override
-                       public void modifyText(ModifyEvent e) {
-                               if(currentTab != null)
-                               {
-                                       String keyword = panelFilterKeyword.getText();
-                                       int index = currentTab.getFilterIndexFromPanel();
-                                       panelFilterIndex.select(index);
-                                         if (keyword != null) {
-                                                 if (index != -1) {
-                                                               currentTab.tableRefill(index, keyword);
-                                                       }
-                                         }
-                               }
-                       }
-               });
-
-               return composite;
-       }
-
-       @Override
-       protected void postCreation() {
-               // pass
-       }
-
-       /**
-        * Sets the focus to the proper object.
-        */
-       @Override
-       public void setFocus() {
-       }
-
-       /**
-        * Copies the current selection of the current filter as multiline text.
-        *
-        * @param clipboard
-        *            The clipboard to place the copied content.
-        */
-       public void copy(Clipboard clipboard) {
-               // get the current table and its selection
-               copyTable(clipboard, currentTab.getTable());
-       }
-
-       /**
-        * Selects all lines.
-        */
-       public void selectAll() {
-               currentTab.getTable().selectAll();
-       }
-
-       /**
-        * Sets a TableFocusListener which will be notified when one of the tables
-        * gets or loses focus.
-        *
-        * @param listener
-        */
-       public void setTableFocusListener(ITableFocusListener listener) {
-               // record the global listener, to make sure table created after
-               // this call will still be setup.
-               globalListener = listener;
-
-               for (LogTab tab : tabs) {
-                       addTableToFocusListener(tab.getTable());
-               }
-       }
-
-       /**
-        * Sets up a Table object to notify the global Table Focus listener when it
-        * gets or loses the focus.
-        *
-        * @param table
-        *            the Table object.
-        */
-       private void addTableToFocusListener(final Table table) {
-               // create the activator for this table
-               final IFocusedTableActivator activator = new IFocusedTableActivator() {
-                       @Override
-                       public void copy(Clipboard clipboard) {
-                               copyTable(clipboard, table);
-                       }
-
-                       @Override
-                       public void selectAll() {
-                               table.selectAll();
-                       }
-               };
-
-               // add the focus listener on the table to notify the global
-               // listener
-               table.addFocusListener(new FocusListener() {
-                       @Override
-                       public void focusGained(FocusEvent e) {
-                               globalListener.focusGained(activator);
-                       }
-
-                       @Override
-                       public void focusLost(FocusEvent e) {
-                               globalListener.focusLost(activator);
-                       }
-               });
-       }
-
-       /**
-        * Copies the current selection of a Table into the provided Clipboard, as
-        * multi-line text.
-        *
-        * @param clipboard
-        *            The clipboard to place the copied content.
-        * @param table
-        *            The table to copy from.
-        */
-       private static void copyTable(Clipboard clipboard, Table table) {
-               int[] selection = table.getSelectionIndices();
-
-               // we need to sort the items to be sure.
-               Arrays.sort(selection);
-
-               // all lines must be concatenated.
-               StringBuilder sb = new StringBuilder();
-
-               // loop on the selection and output the file.
-               for (int i : selection) {
-                       TableItem item = table.getItem(i);
-                       LogMessage msg = (LogMessage) item.getData();
-                       String line = msg.toString();
-                       sb.append(line);
-                       sb.append('\n');
-               }
-
-               // now add that to the clipboard
-               clipboard.setContents(new Object[] { sb.toString() },
-                               new Transfer[] { TextTransfer.getInstance() });
-       }
-
-
-       /**
-        * saves the current selection in a text file.
-        *
-        * @return false if the saving failed.
-        */
-       public boolean save() {
-               if (getCurrentLogTab() == null)
-                       return false;
-               FileDialog dlg = new FileDialog(parent.getShell(), SWT.SAVE);
-
-               dlg.setText(LogUIMessages.Log_Title_Tab_Export);
-               String fileName = String.format(LogUIMessages.Log_File_Tab_Export_Postfix, getCurrentLogTab().getFilterName());
-               dlg.setFileName(fileName);
-               String defaultPath = defaultLogSave;
-               if (defaultPath == null) {
-                       defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
-               }
-               dlg.setFilterPath(defaultPath);
-               dlg.setFilterNames(new String[] { LogUIMessages.Log_File_Tab_Export_Filter });
-               dlg.setFilterExtensions(new String[] { LogUIMessages.Log_File_Tab_Export_Filter_Extensions });
-               File check;
-               boolean again;
-               do {
-                       again = false;
-                       fileName = dlg.open();
-                       if (fileName == null)
-                               return false;
-                       check = new File(fileName);
-                       if (check.exists()) {
-                               int ret = FileDialogUtils.getInstance().checkFileOverwrite(fileName);
-                               if (ret == IDialogConstants.CANCEL_ID)
-                                       again = true;
-                       }
-               } while (again);
-
-               if (fileName != null) {
-                       defaultLogSave = dlg.getFilterPath();
-
-                       // loop on the selection and output the file.
-                       try {
-                               FileWriter writer = new FileWriter(fileName);
-
-                               for (TableItem item : getCurrentLogTab().getTable().getItems()) {
-                                       LogMessage msg = (LogMessage) item.getData();
-                                       String line = msg.toString();
-                                       writer.write(line);
-                                       writer.write('\n');
-                               }
-                               writer.flush();
-
-                       } catch (IOException e) {
-                               return false;
-                       }
-               }
-
-               return true;
-       }
-
-       public void clear() {
-               if (getCurrentLogTab() != null)
-                       this.getCurrentLogTab().clear();
-       }
-
-       private boolean checkTabConnection(LogTab tab, String title)
-       {
-               String deviceName = tab.getFilterDeviceName();
-               if(deviceName == null)
-               {
-                       String tabName = tab.getFilterName();
-                       String message = String.format(LogUIMessages.Log_Message_Tab_Device_Disconnected, tabName);
-                       DialogUtil.openErrorDialog(parent.getShell(), title, message);
-                       return false;
-               }
-               return true;
-       }
-
-       public void addTab() {
-               LogTab tab = getCurrentLogTab();
-               if (tab == null)
-                       return;
-               if(!checkTabConnection(tab, LogUIMessages.Log_Title_Tab_AddTab_Error))
-               {
-                       return ;
-               }
-
-               AddViewDialog dlg = new AddViewDialog(parent.getShell(), tab.getFilterDeviceName());
-               //if base device is already disconnected,
-               if(dlg.getDevice() == null)
-                       return ;
-
-               if (dlg.open()) {
-                       for (IDevice device : SmartDevelopmentBridge.getBridge()
-                                       .getDevices()) {
-                               if (device.getSerialNumber().equals(dlg.getDevice())) {
-
-                                       LogTab newTab = createTab(device, dlg.getName());
-                                       setTabRefresh(newTab);
-                                       initViewFilter(newTab);
-                                       newTab.setPidFilter(dlg.getPidKeyword());
-                                       newTab.setTagFilter(dlg.getTagKeyword());
-                                       newTab.setMsgFilter(dlg.getMsgKeyword());
-
-                                       newTab.startLogTab();
-
-                                       break;
-                               }
-                       }
-               } else
-                       return;
-       }
-
-       public void removeTab() {
-
-               int index = folders.getSelectionIndex();
-               if (index < 0)
-                       return;
-               LogTab tab = tabs.get(index);
-               if (tab.isDefault()) {
-                       return;
-               }
-               tab.stopLogTab(true);
-//             tab.dispose();
-               folders.getItem(index).dispose();
-               tabs.remove(index);
-               tabCnt--;
-               if (!tabs.isEmpty())
-                       folders.setSelection(folders.getItemCount());
-               selectLogTab();
-
-       }
-
-       public void editTab() {
-
-               LogTab oldTab = getCurrentLogTab();
-               if (oldTab == null)
-                       return;
-               if (oldTab.isDefault()) {
-                       return;
-               }
-
-               if(!checkTabConnection(oldTab, LogUIMessages.Log_Title_Tab_EditTab_Error))
-               {
-                       return ;
-               }
-
-               AddViewDialog dlg = new AddViewDialog(parent.getShell(), oldTab);
-               if (dlg.open()) {
-                       for (IDevice device : SmartDevelopmentBridge.getBridge()
-                                       .getDevices()) {
-                               if (device.getSerialNumber().equals(dlg.getDevice())) {
-                                       boolean bRestart = false;
-                                       if (!oldTab.getFilterDeviceName().equals(
-                                                       device.getSerialNumber())) {
-                                               oldTab.stopLogTab(true);
-                                               oldTab.setDevice(device);
-                                               bRestart = true;
-                                       }
-
-                                       for (TabItem item : folders.getItems()) {
-                                               if (item.getText().equals(oldTab.getFilterName())) {
-                                                       item.setText(dlg.getName());
-                                                       oldTab.setFilterName(dlg.getName());
-                                               }
-                                       }
-
-                                       oldTab.setPidFilter(dlg.getPidKeyword());
-                                       oldTab.setTagFilter(dlg.getTagKeyword());
-                                       oldTab.setMsgFilter(dlg.getMsgKeyword());
-
-                                       if (bRestart)
-                                       {
-                                               oldTab.startLogTab();
-                                               setTabRefresh(oldTab);
-                                               initViewFilter(oldTab);
-                                       }
-                                       else
-                                       {
-                                               oldTab.refill();
-                                       }
-                                       break;
-                               }
-                       }
-               } else
-                       return;
-       }
-
-       public static TableColumn createTableColumn(Table parent, String header,
-                       int style, String sampleText) {
-
-               // create the column
-               TableColumn col = new TableColumn(parent, style);
-
-               col.setText(sampleText);
-               col.pack();
-
-               // set the header
-               col.setText(header);
-
-               return col;
-       }
-
-       public LogTab getCurrentLogTab() {
-               if (tabs.size() != 0) {
-                       int index = folders.getSelectionIndex();
-                       LogTab tab = tabs.get(index);
-                       setTabRefresh(tab);
-                       return tab;
-               } else
-                       return null;
-       }
-
-       private void setTabRefresh(LogTab tab)
-       {
-               for(LogTab anytab : tabs)
-               {
-                       anytab.setPendingAsyncRefresh(false);
-               }
-               tab.setPendingAsyncRefresh(true);
-       }
-
-       public void stopAll() {
-               for (LogTab tab : tabs) {
-                       tab.stopLogTab(true);
-               }
-               tabs.clear();
-               tabCnt = 0;
-               folders.dispose();
-       }
-
-       @Override
-       public void deviceConnected(IDevice device) {
-               if (device.isOnline()) {
-                       deviceChanged(device, 1);
-               }
-       }
-
-       @Override
-       public void deviceDisconnected(final IDevice device) {
-               if (parent.isDisposed() == false) {
-                       Display display = parent.getDisplay();
-                       display.asyncExec(new Runnable() {
-                               @Override
-                               public void run() {
-                                       if (parent.isDisposed() == false) {
-                                               String deviceSN = device.getSerialNumber();
-                                               String title = LogUIMessages.Log_Title_View_Device_Disconnected;
-                                               String message = String.format(LogUIMessages.Log_Message_View_Device_Disconnected, deviceSN, deviceSN);
-                                               NotifierDialog.notify(title, message, NotificationType.DISCONNECTED);
-                                       }
-                               }
-                       });
-               }
-
-       }
-
-       @Override
-       public void deviceChanged(final IDevice device, int changeMask) {
-               if (changeMask == 1) {
-                       if (parent.isDisposed() == false) {
-                               Display display = parent.getDisplay();
-                               display.asyncExec(new Runnable() {
-                                       @Override
-                                       public void run() {
-                                               if (folders.isDisposed() == false) {
-                                                       LogTab tab = createDefaultTab(device, null);
-                                                       selectLogTab();
-                                                       tab.startLogTab();
-                                               } else {
-                                                       SmartDevelopmentBridge
-                                                                       .removeDeviceChangeListener(LogPanel.this);
-                                               }
-                                       }
-                               });
-                       }
-               }
-       }
-
-       public void setActionEnabled(int enable) {
-
-               if (enable == ACTION_NOTHING) {
-
-                       addAction.setEnabled(false);
-                       removeAction.setEnabled(false);
-                       editAction.setEnabled(false);
-                       exportAction.setEnabled(false);
-                       clearAction.setEnabled(false);
-                       for (Action a : levelActions) {
-                               a.setEnabled(false);
-                       }
-               } else if (enable == ACTION_DEVICE_TAB) {
-                       addAction.setEnabled(true);
-                       removeAction.setEnabled(false);
-                       editAction.setEnabled(false);
-                       exportAction.setEnabled(true);
-                       clearAction.setEnabled(true);
-                       for (Action a : levelActions) {
-                               a.setEnabled(true);
-                       }
-               } else if (enable == ACTION_ADDITIONAL_TAB) {
-                       addAction.setEnabled(true);
-                       removeAction.setEnabled(true);
-                       editAction.setEnabled(true);
-                       exportAction.setEnabled(true);
-                       clearAction.setEnabled(true);
-                       for (Action a : levelActions) {
-                               a.setEnabled(true);
-                       }
-               }
-       }
+public class LogPanel extends Panel implements IDeviceChangeListener
+{
+
+    //Nothing enabled
+    public static final int NO_TAB = 0;
+    //Only remove disabled
+    public static final int DEVICE_TAB = 1;
+    //Everything enabled
+    public static final int ADDITIONAL_TAB = 2;
+    //Only add, edit disabled
+    public static final int DISCONNECTED_TAB = 3;
+    
+    private final int ENABLE_ADD = 0x0000001;
+    private final int ENABLE_REMOVE = 0x0000010;
+    private final int ENABLE_EDIT = 0x0000100; 
+    private final int ENABLE_SCROLL_LOCK = 0x0001000;
+    private final int ENABLE_EXPORT = 0x0010000;
+    private final int ENABLE_CLEAR = 0x0100000;
+    private final int ENABLE_LEVEL = 0x1000000;
+
+    private final int[] ENABLE_VIEW_ACTIONS= { ENABLE_ADD, ENABLE_REMOVE, ENABLE_EDIT, 
+            ENABLE_SCROLL_LOCK, ENABLE_EXPORT, ENABLE_CLEAR};
+
+    private String defaultLogSave;
+
+    private Composite parent;
+    private TabFolder tabFolder;
+
+    private final LogColors colors;
+
+    private Action[] levelActions;
+    private Action[] viewActions;
+
+    private StackLayout stackLayout;
+
+    public static List<LogTab> logTabList = new ArrayList<LogTab>();
+
+    /** message data, separated from content for multi line messages */
+    protected static class LogMessageInfo
+    {
+        public LogLevel logLevel;
+        public String pidString;
+        public String tag;
+        public String time;
+    }
+
+    private ITableFocusListener globalListener;
+
+    /** message data, separated from content for multi line messages */
+    protected static class LogMessage
+    {
+        public LogMessageInfo data;
+        public String msg;
+
+        @Override
+        public String toString()
+        {
+            return data.time + ": " + data.logLevel + "/" + data.tag + "(" + data.pidString + "): " + msg;
+        }
+    }
+
+    /**
+     * Create the log panel with some default parameters
+     *
+     * @param colors
+     *            The display color object
+     */
+    public LogPanel(LogColors pColors)
+    {
+        colors = pColors;
+    }
+
+    public void setActions(Action[] levelActs, Action[] toolbarActs)
+    {
+        levelActions = levelActs;
+        viewActions = toolbarActs;
+    }
+
+    /**
+     * Creates a control capable of displaying some information. This is called
+     * once, when the application is initializing, from the UI thread.
+     */
+    @Override
+    protected Control createControl(Composite p)
+    {
+        parent = p;
+
+        // create the tab folder
+        tabFolder = new TabFolder(parent, SWT.NONE);
+        tabFolder.setLayoutData(new GridData(GridData.FILL_BOTH));
+        //use stack layout
+        stackLayout = new StackLayout();
+        tabFolder.setLayout(stackLayout);
+        tabFolder.addSelectionListener(new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e)
+            {
+                selectTabItem();
+            }
+        });
+
+        SmartDevelopmentBridge.addDeviceChangeListener(this);
+        // Create default device tab if device(s) is connected
+         createDefaultTabs();
+        return null;
+    }
+
+    @Override
+    protected void postCreation()
+    {
+    }
+
+    /**
+     * Sets the focus to the proper object.
+     */
+    @Override
+    public void setFocus()
+    {
+    }
+
+    /**
+     * do something when select TabItem
+     */
+    private void selectTabItem()
+    {
+        int index = tabFolder.getSelectionIndex();
+        if(index == -1)
+        {
+            return ;
+        }
+        TabItem item = tabFolder.getItem(index);
+        LogTab logTab = getSelectionLogTab();
+        if(logTab == null)
+        {
+            return ;
+        }
+
+        setEnableAndCheckState(logTab);
+        stackLayout.topControl = item.getControl();
+    }
+
+
+    /**
+     * Set action enable state depending on a logTab type.
+     * And then set check state.
+     * @param logTab
+     */
+    private void setEnableAndCheckState(LogTab logTab)
+    {
+        String serial = logTab.getDeviceSerialNumber();
+        //if device is disconnected, only remove enabled.
+        if(serial == null)
+        {
+            setEnabledForActions(LogPanel.DISCONNECTED_TAB);
+        }
+        else
+        {
+            if (logTab.isDefault())
+            {
+                setEnabledForActions(LogPanel.DEVICE_TAB);
+            }
+            else
+            {
+                setEnabledForActions(LogPanel.ADDITIONAL_TAB);
+            }
+        }
+        setCheckActionState(logTab);
+    }
+
+    /**
+     * When user selects level icons, set level values and filter messages.
+     * @param level level type(Debug, Info, Error..)
+     * @param setCheck is Checked or not
+     */
+    public void setLevel(int level, boolean setCheck)
+    {
+        int levelMode = getSelectionLogTab().getLevelMode();
+        level = (int) Math.pow(2, level);
+
+        if (setCheck)
+        {
+            levelMode |= level;
+        }
+        else
+        {
+            levelMode &= (~level);
+        }
+
+        getSelectionLogTab().setLevelMode(levelMode);
+        getSelectionLogTab().filterMessages();
+    }
+
+    // create the logtab with default devices
+    private void createDefaultTabs()
+    {
+        for (IDevice device : getDevices())
+        {
+            if (device.isOffline())
+                continue;
+            LogTab dTab = createLogTab(ConnectionExplorerLabelProvider.getDeviceSerialWithName(device), device, true);
+            dTab.start();
+        }
+    }
+    
+    /**
+     * Create LogTab and TabItem and
+     * set action and icon status
+     * @param device IDevice to get logs
+     * @param name logtab name
+     * @param isDefault check this is default logtab for device
+     * @return
+     */
+    private LogTab createLogTab(String name, IDevice device, boolean isDefault)
+    {
+        Iterator<LogTab> iter = logTabList.iterator();
+        while( iter.hasNext())
+        {
+            LogTab oldTab = iter.next();
+            if(oldTab.getLogTabName().equals(name))
+            {
+                removeTab(oldTab);
+                iter.remove();
+            }
+        }
+
+        LogTab logTab = new LogTab(name, device, colors);
+        if (isDefault)
+        {
+
+            logTab.setDefault();
+            setEnabledForActions(LogPanel.DEVICE_TAB);
+        } else
+        {
+            setEnabledForActions(LogPanel.ADDITIONAL_TAB);
+        }
+        setCheckActionState(logTab);
+
+        logTabList.add(logTab);
+        createTabItem(tabFolder, logTab);
+
+        return logTab;
+    }
+
+    /**
+     * create TabItem and set to LogTab
+     * @param tabFolder
+     * @param logTab
+     * @return
+     */
+    private Control createTabItem(TabFolder tabFolder, final LogTab logTab)
+    {
+        // Create a composite and add four buttons to it
+        Composite composite = new Composite(tabFolder, SWT.NONE);
+        composite.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+        composite.setLayout(new GridLayout(1, false));
+
+        Composite top = new Composite(composite, SWT.NONE);
+        top.setLayoutData(new GridData(GridData.FILL_BOTH));
+        top.setLayout(new FillLayout());
+
+        final Table table = new Table(top, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER | SWT.H_SCROLL);
+
+        table.setHeaderVisible(true);
+        table.setLinesVisible(true);
+
+        if (globalListener != null)
+        {
+            addTableToFocusListener(table);
+        }
+
+        ControlListener listener = null;
+        listener = new ControlListener()
+        {
+            @Override
+            public void controlMoved(ControlEvent e)
+            {
+            }
+
+            @Override
+            public void controlResized(ControlEvent e)
+            {
+                Rectangle r = table.getClientArea();
+
+                // get the size of all but the last column
+                int total = table.getColumn(0).getWidth();
+                total += table.getColumn(1).getWidth();
+                total += table.getColumn(2).getWidth();
+                total += table.getColumn(3).getWidth();
+                //
+                if (r.width > total)
+                {
+                    table.getColumn(4).setWidth(r.width - total);
+                }
+            }
+        };
+
+        table.addControlListener(listener);
+
+        TableColumn col = createTableColumn(table, "Time", SWT.LEFT, "00-00 00:00:00.000");
+        col.addControlListener(listener);
+
+        col = createTableColumn(table, "Level", SWT.LEFT, "Verbose");
+        col.addControlListener(listener);
+
+        col = createTableColumn(table, "Pid", SWT.LEFT, "9999999");
+        col.addControlListener(listener);
+
+        col = createTableColumn(table, "Tag", SWT.LEFT, "ABCDEFGHIJK");
+        col.addControlListener(listener);
+
+        col = createTableColumn(table, "Message", SWT.LEFT, "abcdefghijklmnopqrstuvwxyz0123456789");
+        // col.setResizable(false);
+
+        Composite bottom = new Composite(composite, SWT.NONE);
+        bottom.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        bottom.setLayout(new GridLayout(3, false));
+
+        Combo filterComboOnView = new Combo(bottom, SWT.READ_ONLY);
+        String[] comboItems = { "Pid", "Tag", "Message" };
+        filterComboOnView.setItems(comboItems);
+        filterComboOnView.select(2);
+        filterComboOnView.setToolTipText(LogUIMessages.Log_Tooltip_View_Filter_Combo);
+        filterComboOnView.addSelectionListener(new SelectionListener()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e)
+            {
+                Combo combo = (Combo) e.widget;
+                getSelectionLogTab().setFilterCombo(combo.getSelectionIndex());
+                getSelectionLogTab().filterMessages();
+            }
+
+            @Override
+            public void widgetDefaultSelected(SelectionEvent e)
+            {
+            }
+        });
+
+        Text filterTextOnView = new Text(bottom, SWT.SINGLE | SWT.BORDER);
+        filterTextOnView.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        filterTextOnView.setMessage(LogUIMessages.Log_Message_View_Filter_Text);
+        filterTextOnView.addModifyListener(new ModifyListener()
+        {
+            @Override
+            public void modifyText(ModifyEvent e)
+            {
+                Text text = (Text) e.widget;
+                getSelectionLogTab().setFilterText(text.getText());
+                getSelectionLogTab().filterMessages();
+            }
+        });
+
+        TabItem tabItem = new TabItem(tabFolder, SWT.NONE, tabFolder.getItemCount());
+        tabItem.setText(logTab.getLogTabName());
+        tabItem.setControl(composite);
+        logTab.setTable(table);
+        logTab.setTabItem(tabItem);
+        tabFolder.setSelection(tabItem);
+        stackLayout.topControl = tabItem.getControl();
+
+        return composite;
+    }
+
+    /**
+     * Copies the current selection of the current filter as multiline text.
+     *
+     * @param clipboard
+     *            The clipboard to place the copied content.
+     */
+    public void copy(Clipboard clipboard)
+    {
+        // get the current table and its selection
+        copyTable(clipboard, getSelectionLogTab().getTable());
+    }
+
+    /**
+     * Selects all lines.
+     */
+    public void selectAll()
+    {
+        getSelectionLogTab().getTable().selectAll();
+    }
+
+    /**
+     * Sets a TableFocusListener which will be notified when one of the tables
+     * gets or loses focus.
+     *
+     * @param listener
+     */
+    public void setTableFocusListener(ITableFocusListener listener)
+    {
+        // record the global listener, to make sure table created after
+        // this call will still be setup.
+        globalListener = listener;
+
+        for (LogTab tab : logTabList)
+        {
+            addTableToFocusListener(tab.getTable());
+        }
+    }
+
+    /**
+     * Sets up a Table object to notify the global Table Focus listener when it
+     * gets or loses the focus.
+     *
+     * @param table
+     *            the Table object.
+     */
+    private void addTableToFocusListener(final Table table)
+    {
+        // create the activator for this table
+        final IFocusedTableActivator activator = new IFocusedTableActivator()
+        {
+            @Override
+            public void copy(Clipboard clipboard)
+            {
+                copyTable(clipboard, table);
+            }
+
+            @Override
+            public void selectAll()
+            {
+                table.selectAll();
+            }
+        };
+
+        // add the focus listener on the table to notify the global
+        // listener
+        table.addFocusListener(new FocusListener()
+        {
+            @Override
+            public void focusGained(FocusEvent e)
+            {
+                globalListener.focusGained(activator);
+            }
+
+            @Override
+            public void focusLost(FocusEvent e)
+            {
+                globalListener.focusLost(activator);
+            }
+        });
+    }
+
+    /**
+     * Copies the current selection of a Table into the provided Clipboard, as
+     * multi-line text.
+     *
+     * @param clipboard
+     *            The clipboard to place the copied content.
+     * @param table
+     *            The table to copy from.
+     */
+    private static void copyTable(Clipboard clipboard, Table table)
+    {
+        int[] selection = table.getSelectionIndices();
+
+        // we need to sort the items to be sure.
+        Arrays.sort(selection);
+
+        // all lines must be concatenated.
+        StringBuilder sb = new StringBuilder();
+
+        // loop on the selection and output the file.
+        for (int i : selection)
+        {
+            TableItem item = table.getItem(i);
+            LogMessage msg = (LogMessage) item.getData();
+            String line = msg.toString();
+            sb.append(line);
+            sb.append('\n');
+        }
+
+        // now add that to the clipboard
+        clipboard.setContents(new Object[] { sb.toString() }, new Transfer[] { TextTransfer.getInstance() });
+    }
+
+    public boolean save()
+    {
+        if (getSelectionLogTab() == null)
+            return false;
+        FileDialog dlg = new FileDialog(parent.getShell(), SWT.SAVE);
+
+        dlg.setText(LogUIMessages.Log_Title_Tab_Export);
+        String saveName = String.format(LogUIMessages.Log_File_Tab_Export_Postfix, getSelectionLogTab().getLogTabName());
+
+        dlg.setFileName(saveName);
+        String defaultPath = defaultLogSave;
+        if (defaultPath == null)
+        {
+            defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
+        }
+        dlg.setFilterPath(defaultPath);
+        dlg.setFilterNames(new String[] { LogUIMessages.Log_File_Tab_Export_Filter });
+        dlg.setFilterExtensions(new String[] { LogUIMessages.Log_File_Tab_Export_Filter_Extensions });
+
+        String fileName = null;
+        boolean again;
+        do
+        {
+            File checkFile;
+            again = false;
+            fileName = dlg.open();
+            if (fileName == null)
+                return false;
+            checkFile = new File(fileName);
+            if (checkFile.exists())
+            {
+                int ret = FileDialogUtils.allowFileOverwrite(fileName);
+                if( ret == IDialogConstants.CANCEL_ID)
+                    again = true;
+            }
+        } while (again);
+
+        defaultLogSave = dlg.getFilterPath();
+
+        // loop on the selection and output the file.
+        try
+        {
+            FileWriter writer = new FileWriter(fileName);
+
+            for (TableItem item : getSelectionLogTab().getTable().getItems())
+            {
+                LogMessage msg = (LogMessage) item.getData();
+                String line = msg.toString();
+                writer.write(line);
+                writer.write('\n');
+            }
+            writer.flush();
+
+        } catch (IOException e)
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     *
+     */
+    public void clear()
+    {
+        LogTab tab = getSelectionLogTab();
+        if ( tab != null)
+            tab.clear();
+    }
+
+    /**
+     * check whether device is still connected or not
+     * then notify with dialog
+     *
+     * @param tab target to check device connection
+     * @param title dialog title
+     * @return  if device is disconnected, return false
+     */
+    private boolean checkTabConnection(LogTab tab, String title)
+    {
+        String deviceName = tab.getDeviceSerialNumber();
+        if (deviceName == null)
+        {
+            String tabName = tab.getLogTabName();
+            String message = String.format(LogUIMessages.Log_Message_Tab_Device_Disconnected, tabName);
+            DialogUtil.openErrorDialog(parent.getShell(), title, message);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * add addtional TabItem and LogTab
+     */
+    public void addTab()
+    {
+        LogTab tab = getSelectionLogTab();
+
+        if (tab == null)
+            return;
+
+        if (!checkTabConnection(tab, LogUIMessages.Log_Title_Tab_AddTab_Error))
+        {
+            return;
+        }
+
+        AddViewDialog dlg = new AddViewDialog(parent.getShell(), tab.getDeviceSerialNumber());
+
+        if (dlg.getDevice() == null)
+            return;
+
+        if (dlg.open())
+        {
+            for (IDevice device : getDevices())
+            {
+                if (device.getSerialNumber().equals(dlg.getDevice()))
+                {
+
+                    LogTab newTab = createLogTab(dlg.getName(), device, false);
+                    // set filter values from addViewDialog
+                    newTab.setPidFilter(dlg.getPidKeyword());
+                    newTab.setTagFilter(dlg.getTagKeyword());
+                    newTab.setMsgFilter(dlg.getMsgKeyword());
+
+                    newTab.start();
+
+                    break;
+                }
+            }
+        } else
+            return;
+    }
+
+    public void removeTab(LogTab tab)
+    {
+        tab.stop(true);
+        SWTUtil.tryDispose(tab.getTabItem());
+    }
+
+    /**
+     * remove selected TabItem and LogTab
+     */
+    public void removeTab()
+    {
+        int index = tabFolder.getSelectionIndex();
+        if (index < 0)
+            return;
+        LogTab tab = logTabList.get(index);
+        removeTab(tab);
+        logTabList.remove(tab);
+        if(logTabList.isEmpty())
+        {
+            setEnabledForActions(NO_TAB);
+        }
+    }
+
+    /**
+     * edit selected TabItem and LogTab
+     */
+    public void editTab()
+    {
+
+        LogTab oldTab = getSelectionLogTab();
+
+        if (oldTab == null)
+            return;
+
+        if (oldTab.isDefault())
+        {
+            return;
+        }
+
+        if (!checkTabConnection(oldTab, LogUIMessages.Log_Title_Tab_EditTab_Error))
+        {
+            return;
+        }
+
+        AddViewDialog dlg = new AddViewDialog(parent.getShell(), oldTab);
+        if (dlg.open())
+        {
+            for (IDevice device : getDevices())
+            {
+                if (device.getSerialNumber().equals(dlg.getDevice()))
+                {
+                    oldTab.stop(true);
+                    oldTab.setDevice(device);
+
+                    for (TabItem item : tabFolder.getItems())
+                    {
+                        if (item.getText().equals(oldTab.getLogTabName()))
+                        {
+                            item.setText(dlg.getName());
+                            oldTab.setLogTabName(dlg.getName());
+                        }
+                    }
+
+                    oldTab.setPidFilter(dlg.getPidKeyword());
+                    oldTab.setTagFilter(dlg.getTagKeyword());
+                    oldTab.setMsgFilter(dlg.getMsgKeyword());
+
+                    oldTab.start();
+
+                    break;
+                }
+            }
+        }
+    }
+
+    public static TableColumn createTableColumn(Table parent, String header, int style, String sampleText)
+    {
+
+        // create the column
+        TableColumn col = new TableColumn(parent, style);
+
+        col.setText(sampleText);
+        col.pack();
+
+        // set the header
+        col.setText(header);
+
+        return col;
+    }
+
+    /**
+     * get selected logtab from tabitem on folder
+     * @return
+     */
+    public LogTab getSelectionLogTab()
+    {
+        if (logTabList.size() != 0)
+        {
+            int index = tabFolder.getSelectionIndex();
+            TabItem item = tabFolder.getItem(index);
+
+            for(LogTab logTab : logTabList)
+            {
+                if(logTab.getTabItem() == item)
+                    return logTab;
+            }
+        }
+        return null;
+    }
+
+    public void stopAllTabItems()
+    {
+        for (LogTab tab : logTabList)
+        {
+            removeTab(tab);
+        }
+        logTabList.clear();
+    }
+
+    private IDevice[] getDevices()
+    {
+        IDevice[] devices;
+        SmartDevelopmentBridge sdbBridge = SmartDevelopmentBridge.getBridge();
+        if(sdbBridge != null)
+            devices = sdbBridge.getDevices();
+        else
+            devices = new IDevice[0];
+        return devices;
+    }
+
+    @Override
+    public void deviceConnected(IDevice device)
+    {
+        if (device.isOnline())
+        {
+            deviceChanged(device, 1);
+        }
+    }
+
+    @Override
+    public void deviceDisconnected(final IDevice device)
+    {
+
+        if (parent.isDisposed() == false)
+        {
+            Display display = parent.getDisplay();
+            display.asyncExec(new Runnable()
+            {
+                @Override
+                public void run()
+                {
+                    if (parent.isDisposed() == false)
+                    {
+                        String name = ConnectionExplorerLabelProvider.getDeviceSerialWithName(device);
+                        String title = LogUIMessages.Log_Title_View_Device_Disconnected;
+                        String message = String.format(LogUIMessages.Log_Message_View_Device_Disconnected, name, name);
+                        NotifierDialog.notify(title, message, NotificationType.DISCONNECTED);
+                        for( LogTab tab : logTabList)
+                        {
+                            if(device.getSerialNumber().equals(tab.getDeviceSerialNumber()))
+                            {
+                                tab.setDevice(null);
+                            }
+                        }
+                        setEnabledForActions(LogPanel.DISCONNECTED_TAB);
+
+                    } else
+                    {
+                        SmartDevelopmentBridge.removeDeviceChangeListener(LogPanel.this);
+                    }
+                }
+            });
+        }
+    }
+
+    @Override
+    public void deviceChanged(final IDevice device, int changeMask)
+    {
+        if (changeMask == 1)
+        {
+            if (parent.isDisposed() == false)
+            {
+                Display display = parent.getDisplay();
+                display.asyncExec(new Runnable()
+                {
+                    @Override
+                    public void run()
+                    {
+                        if (tabFolder.isDisposed() == false)
+                        {
+                            LogTab tab = createLogTab(ConnectionExplorerLabelProvider.getDeviceSerialWithName(device), device, true);
+                            tab.start();
+                        } else
+                        {
+                            SmartDevelopmentBridge.removeDeviceChangeListener(LogPanel.this);
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Get enabled state for each action with state value.
+     * @param state
+     * @param action
+     * @return
+     */
+    private boolean getEnabled(int state, int action)
+    {
+        int result = (state & action);
+        return result != 0 ? true : false;
+    }
+
+    private void setEnableState(int state)
+    {
+        for(int i = 0; i < viewActions.length; i++)
+        {
+            viewActions[i].setEnabled(getEnabled(state, ENABLE_VIEW_ACTIONS[i]));
+        }
+
+        boolean check = getEnabled(state, ENABLE_LEVEL);
+        for (Action level : levelActions)
+        {
+            level.setEnabled(check);
+        }
+    }
+
+    /**
+     * Set checked state for action(loglevel, scroll lock) depending on a logTab
+     * when create new logtab or select the logtab.
+     */
+    private void setCheckActionState(LogTab tab)
+    {
+        int levelMode = tab.getLevelMode();
+        for (int i = 0; i < 5; i++)
+        {
+            int a = levelMode & (0x1 << i);
+            levelActions[i].setChecked(a == (int) Math.pow(2, i));
+        }
+
+        //Scroll lock action is toggle action
+        viewActions[3].setChecked(tab.getScrollLock());
+    }
+
+    /**
+     * Get enabled state for action depending on a logTab type.
+     */
+    public int getEnabledStateForActions(int tabType)
+    {
+        int enable = 0x0000000;
+
+        if (tabType == NO_TAB)
+        {
+        }
+        else if (tabType == DEVICE_TAB)
+        {
+            enable = ENABLE_ADD | ENABLE_SCROLL_LOCK | ENABLE_EXPORT | ENABLE_CLEAR | ENABLE_LEVEL;
+        }
+        else if (tabType == ADDITIONAL_TAB)
+        {
+            enable = ENABLE_ADD | ENABLE_REMOVE | ENABLE_EDIT | ENABLE_SCROLL_LOCK | ENABLE_EXPORT | ENABLE_CLEAR | ENABLE_LEVEL;
+        }
+        else if (tabType == DISCONNECTED_TAB)
+        {
+            enable = ENABLE_REMOVE | ENABLE_EXPORT | ENABLE_LEVEL;
+        }
+
+        return enable;
+    }
+
+    /**
+     * Get enabled state and set enabled state for action depending on a logTab type
+     * (NO_TAB, DEVICE_TAB, ADDITIONAL_TAB).
+     * @param tabType
+     */
+    public void setEnabledForActions(int tabType)
+    {
+        int mode = getEnabledStateForActions(tabType);
+        setEnableState(mode);
+    }
+
+    /**
+     * Set scroll locked or unlocked.
+     * @param lock
+     */
+    public void setScrollLock(boolean lock)
+    {
+        getSelectionLogTab().setScrollLock(lock);
+    }
 }
\ No newline at end of file
index 9c6f574..bfd7b6d 100644 (file)
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact:
-* Hoon Kang <h245.kang@samsung.com>
-* Hyunsik Noh <hyunsik.noh@samsung.com>
-*
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hoon Kang <h245.kang@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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
-*
-*/
+ * 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.common.connection.log;
 
 import java.util.ArrayList;
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.eclipse.jface.action.Action;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTException;
 import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.ScrollBar;
 import org.eclipse.swt.widgets.TabItem;
 import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.TableItem;
 import org.tizen.common.connection.log.LogPanel.LogMessage;
 import org.tizen.common.connection.log.LogPanel.LogMessageInfo;
-import org.tizen.common.console.AnsicodeAdapter;
+import org.tizen.common.ui.view.console.AnsicodeAdapter;
+import org.tizen.common.util.StringUtil;
+import org.tizen.common.util.log.Logger;
 import org.tizen.sdblib.IDevice;
-import org.tizen.sdblib.Log;
 import org.tizen.sdblib.Log.LogLevel;
 import org.tizen.sdblib.MultiLineReceiver;
 
-public class LogTab {
-
-       private static final int STRING_BUFFER_LENGTH = 10000;
-
-       public static final int FILTER_NONE = -1;
-       public static final int FILTER_PID = 0x0;
-       public static final int FILTER_TAG = 0x1;
-       public static final int FILTER_MSG = 0x2;
-
-       public static final int LEVEL_ALL = 0x1F;
-       public static final int LEVEL_VERBOSE = 0x1;
-       public static final int LEVEL_DEBUG = 0x2;
-       public static final int LEVEL_INFO = 0x4;
-       public static final int LEVEL_WARNING = 0x8;
-       public static final int LEVEL_ERROR = 0x16;
-
-       /**
-        * Single level log level as defined in Log.mLevelChar. Only valid if mMode
-        * is MODE_LEVEL
-        */
-       private int levelMode = LEVEL_ALL;
-
-       private String[] pidFilter = null;
-       private String[] tagFilter = null;
-       private String[] msgFilter = null;
-
-       private String pidFilterString = null;
-       private String tagFilterString = null;
-       private String msgFilterString = null;
-
-       private int filterIndexFromPanel = FILTER_MSG;
-       private String filterKeywordFromPanel = "";
-
-       private String filterName = null;
-       private IDevice filterDevice = null;
-       private LogTabOuputReceiver logger = null;
-       private LogColors colors;
-
-       private Table table;
-       private TabItem tabItem;
-
-       private static Pattern logPattern = Pattern
-                       .compile("^\\[\\s(\\d\\d-\\d\\d\\s\\d\\d:\\d\\d:\\d\\d\\.\\d+)" + //$NON-NLS-1$
-                                       "\\s+(\\d*):\\s*(\\d+)\\s([VDIWE])/(.+)\\s+\\]$");
-
-       private final ArrayList<LogMessage> tableMessages = new ArrayList<LogMessage>();
-       private final ArrayList<LogMessage> newMessages = new ArrayList<LogMessage>();
-       private final LogMessage[] buffer = new LogMessage[STRING_BUFFER_LENGTH];
-
-       private LogMessageInfo lastMessageInfo = null;
-       private boolean pendingAsyncRefresh = false;
-
-       private boolean isDefault = false;
-       private int removedMessageCount = 0;
-
-       private int indexStart = -1;
-       private int indexEnd = -1;
-
-       public LogTab(String pName, IDevice pDevice, LogColors pColors) {
-               filterName = pName;
-               filterDevice = pDevice;
-               this.colors = pColors;
-       }
-
-       public LogTab() {
-       }
-
-       /** Sets the name of the filter. */
-       public void setFilterName(String name) {
-               filterName = name;
-       }
-
-       public void setPidFilter(String pid) {
-               pidFilterString = pid;
-               if (pid != null)
-                       pidFilter = setFilter(pid.split("[\\s\t,]"));
-               else
-                       pidFilter = null;
-       }
-
-       public void setTagFilter(String tag) {
-               tagFilterString = tag;
-               if (tag != null)
-                       tagFilter = setFilter(tag.split("[\\s\t,]"));
-               else
-                       tagFilter = null;
-       }
-
-       public void setMsgFilter(String msg) {
-               msgFilterString = msg;
-               if (msg != null)
-                       msgFilter = setFilter(msg.split("[\\s\t,]"));
-               else
-                       msgFilter = null;
-       }
-
-       private String[] setFilter(String[] array) {
-               ArrayList<String> result = new ArrayList<String>();
-               for (String s : array) {
-                       if (s.length() > 0) {
-                               result.add(s);
-                       }
-               }
-               return result.toArray(new String[(result.size())]);
-       }
-
-       public String getFilterName() {
-               return filterName;
-       }
-
-       public int getLevelMode() {
-               return levelMode;
-       }
-
-       public String getPidFilter() {
-               return pidFilterString;
-       }
-
-       public String getTagFilter() {
-               return tagFilterString;
-       }
-
-       public String getMsgFilter() {
-               return msgFilterString;
-       }
-
-       public String getFilterDeviceName() {
-               if(filterDevice != null)
-                       return filterDevice.getSerialNumber();
-               else
-                       return null;
-       }
-
-       public void setTab(TabItem pTabItem) {
-               tabItem = pTabItem;
-       }
-
-       public void setTable(Table pTable) {
-               table = pTable;
-       }
-
-       public boolean uiReady() {
-               return (table != null && tabItem != null);
-       }
-
-       /**
-        * Returns the UI table object.
-        *
-        * @return
-        */
-       public Table getTable() {
-               return table;
-       }
-
-       public void dispose() {
-               Display d = tabItem.getDisplay();
-
-               d.syncExec(new Runnable() {
-                       @Override
-                       public void run() {
-                               if (tabItem.isDisposed() == false) {
-                                       tabItem.dispose();
-                               }
-                       }
-               });
-               table = null;
-               tabItem = null;
-       }
-
-       public void startLogTab() {
-
-               resetUI(false);
-
-               if (filterDevice != null) {
-
-                       // create a new output receiver
-                       logger = new LogTabOuputReceiver();
-
-                       // start the LogTab in a different thread
-                       new Thread(filterDevice.getSerialNumber() + " Logger") { //$NON-NLS-1$
-                               @Override
-                               public void run() {
-
-                                       while (filterDevice.isOnline() == false && logger != null && logger.isCancelled == false) {
-                                               try {
-                                                       sleep(2000);
-                                               } catch (InterruptedException e) {
-                                                       Log.e("LogTab",
-                                                                       "Device is not online or logger is null/cancelled");
-                                                       return;
-                                               }
-                                       }
-
-                                       if (logger == null || logger.isCancelled) {
-                                               return;
-                                       }
-
-                                       try {
-
-                                               filterDevice.executeShellCommand(
-                                                               "dlogutil -v long *:v", logger, 0 /* timeout */); //$NON-NLS-1$
-                                       } catch (Exception e) {
-                                               Log.e("LogTab", e);
-                                       } finally {
-                                               logger = null;
-                                               filterDevice = null;
-                                               stopLogTab(false);
-                                       }
-                               }
-                       } .start();
-               }
-       }
-
-       /** Stop the current LogTab */
-       public void stopLogTab(boolean inUiThread) {
-               if (logger != null) {
-                       logger.isCancelled = true;
-
-                       logger = null;
-
-                       clear();
-
-                       resetUI(inUiThread);
-               }
-       }
-
-       //add message to tableMessages(filtered message) and replace old message to new message
-       public boolean addMessage(LogMessage newMessage, LogMessage oldMessage) {
-               synchronized (tableMessages) {
-                       if (oldMessage != null) {
-                               int index = tableMessages.indexOf(oldMessage);
-                               if (index != -1) {
-                                       tableMessages.remove(index);
-                                       removedMessageCount++;
-                               }
-
-                               index = tableMessages.indexOf(oldMessage);
-                               if (index != -1) {
-                                       tableMessages.remove(index);
-                               }
-                       }
-
-                       boolean filter = accept(newMessage);
-
-                       if (filter) {
-                               tableMessages.add(newMessage);
-                               newMessages.add(newMessage);
-                       }
-
-                       return filter;
-               }
-       }
-
-       boolean accept(LogMessage logMessage) {
-               if (logMessage == null)
-                       return false;
-
-               if (levelMode != LEVEL_ALL) {
-                       int a = 0;
-                       a = (levelMode & (0x1 << (logMessage.data.logLevel.getPriority() - 2)));
-
-                       if (a == 0)
-                               return false;
-               }
-
-               if (pidFilter != null || tagFilter != null || msgFilter != null) {
-                       if (pidFilter != null) {
-                               for (String filter : pidFilter) {
-                                       if (logMessage.data.pidString.contains(
-                                                       filter))
-                                               if (tableAccept(logMessage))
-                                                       return true;
-                               }
-                       }
-
-                       if (tagFilter != null) {
-                               for (String filter : tagFilter) {
-                                       if (logMessage.data.tag.toLowerCase().contains(
-                                                       filter.toLowerCase()))
-                                               if (tableAccept(logMessage))
-                                                       return true;
-                               }
-                       }
-
-                       if (msgFilter != null) {
-                               for (String filter : msgFilter) {
-                                       if (logMessage.msg.toLowerCase().contains(
-                                                       filter.toLowerCase()))
-                                               if (tableAccept(logMessage))
-                                                       return true;
-                               }
-                       }
-                       return false;
-               }
-               if (tableAccept(logMessage))
-                       return true;
-               else
-                       return false;
-       }
-
-       public void flush() {
-
-               ScrollBar bar = table.getVerticalBar();
-               boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
-
-               int topIndex = table.getTopIndex();
-
-               table.setRedraw(false);
-
-               int totalCount = newMessages.size();
-
-               try {
-                       // remove the items of the old messages.
-                       for (int i = 0; i < removedMessageCount && table.getItemCount() > 0; i++) {
-                               table.remove(0);
-                       }
-
-                       // add the new items
-                       for (int i = 0; i < totalCount; i++) {
-                               LogMessage msg = newMessages.get(i);
-                               addTableItem(msg);
-                       }
-               } catch (SWTException e) {
-                       // log the error and keep going. Content of the LogTab
-                       // table maybe unexpected
-                       // but at least ddms won't crash.
-                       Log.e("LogFilter", e);
-               }
-
-               // redraw
-               table.setRedraw(true);
-
-               // scroll if needed, by showing the last item
-               if (scroll) {
-                       totalCount = table.getItemCount();
-                       if (totalCount > 0) {
-                               table.showItem(table.getItem(totalCount - 1));
-                       }
-               } else if (removedMessageCount > 0) {
-                       // we need to make sure the topIndex is still visible.
-                       // Because really old items are removed from the list, this
-                       // could make it disappear
-                       // if we don't change the scroll value at all.
-
-                       topIndex -= removedMessageCount;
-                       if (topIndex < 0) {
-                               // looks like it disappeared. Lets just show the
-                               // first item
-                               table.showItem(table.getItem(0));
-                       } else {
-                               table.showItem(table.getItem(topIndex));
-                       }
-               }
-
-               newMessages.clear();
-               removedMessageCount = 0;
-
-       }
-
-       void setColors(LogColors pColors) {
-               colors = pColors;
-       }
-
-       /**
-        * Add a TableItem for the index-th item of the buffer
-        *
-        * @param filter
-        *            The index of the table in which to insert the item.
-        */
-       private void addTableItem(LogMessage msg) {
-               TableItem item = new TableItem(table, SWT.NONE);
-               item.setText(0, msg.data.time);
-               // item.setText(1,
-               // new String(new char[]{msg.data.logLevel.getPriorityLetter()}));
-               item.setText(2, msg.data.pidString);
-               item.setText(3, msg.data.tag);
-               item.setText(4, msg.msg);
-
-               // add the buffer index as data
-               item.setData(msg);
-
-               if (msg.data.logLevel == LogLevel.INFO) {
-                       item.setForeground(colors.infoColor);
-                       item.setText(1, "Info");
-               } else if (msg.data.logLevel == LogLevel.DEBUG) {
-                       item.setForeground(colors.debugColor);
-                       item.setText(1, "Debug");
-               } else if (msg.data.logLevel == LogLevel.ERROR) {
-                       item.setForeground(colors.errorColor);
-                       item.setText(1, "Error");
-               } else if (msg.data.logLevel == LogLevel.WARN) {
-                       item.setForeground(colors.warningColor);
-                       item.setText(1, "Warn");
-               } else if (msg.data.logLevel == LogLevel.WARN) {
-                       item.setForeground(colors.verboseColor);
-                       item.setText(1, "Verbose");
-               }
-       }
-
-       /**
-        * objects able to receive the output of a remote shell command,
-        * specifically a LogTab command in this case
-        */
-       private final class LogTabOuputReceiver extends MultiLineReceiver {
-
-               public boolean isCancelled = false;
-
-               public LogTabOuputReceiver() {
-                       super();
-
-                       setTrimLine(false);
-               }
-
-               @Override
-               public void processNewLines(String[] lines) {
-                       if (isCancelled == false) {
-                               processLogLines(lines);
-                       }
-               }
-
-               @Override
-               public boolean isCancelled() {
-                       return isCancelled;
-               }
-       }
-
-       /**
-        * Process new Log lines coming from {@link LogCatOuputReceiver}.
-        *
-        * @param lines the new lines
-        */
-       protected void processLogLines(String[] lines) {
-               // WARNING: this will not work if the string contains more line
-               // than
-               // the buffer holds.
-
-               if (lines.length > STRING_BUFFER_LENGTH) {
-                       Log.e("LogTab", "Receiving more lines than STRING_BUFFER_LENGTH");
-               }
-
-               // parse the lines and create LogMessage that are stored in a
-               // temporary list
-               final ArrayList<LogMessage>newMessages = new ArrayList<LogMessage>();
-
-               synchronized (buffer) {
-                       for (String line : lines) {
-                               line = AnsicodeAdapter.getStripAnsiString(line);
-                               // ignore empty lines.
-                               if (line.length() > 0) {
-                                       // check for header lines.
-                                       Matcher matcher = logPattern.matcher(line);
-                                       if (matcher.matches()) {
-                                               // this is a header line, parse the header and keep it around.
-                                               lastMessageInfo = new LogMessageInfo();
-
-                                               lastMessageInfo.time = matcher.group(1);
-                                               lastMessageInfo.pidString = matcher.group(2);
-                                               lastMessageInfo.logLevel = LogLevel
-                                                               .getByLetterString(matcher.group(4));
-                                               lastMessageInfo.tag = matcher.group(5).trim();
-                                       } else {
-
-                                               if (lastMessageInfo == null) {
-                                                       return;
-                                               }
-
-                                               // This is not a header line.
-                                               // Create a new LogMessage and process it.
-                                               LogMessage mc = new LogMessage();
-
-                                               // If someone printed a log message with embedded '\n' characters,
-                                               //there will one header line followed by multiple text lines.
-                                               // Use the last header that we saw.
-                                               mc.data = lastMessageInfo;
-
-                                               // tabs seem to display as only 1 tab so we replace the leading tabs by 4 spaces.
-                                               mc.msg = line.replaceAll("\t", "    "); //$NON-NLS-1$ //$NON-NLS-2$
-
-                                               // process the new LogMessage.
-                                               processNewMessage(mc);
-
-                                               // store the new LogMessage
-                                               newMessages.add(mc);
-                                       }
-                               }
-                       }
-
-                       if (pendingAsyncRefresh) {
-//                             pendingAsyncRefresh = true;
-
-                               try {
-                                       Display display = table.getDisplay();
-
-                                       // run in sync because this will update the
-                                       // buffer start/end indices
-                                       display.asyncExec(new Runnable() {
-                                               @Override
-                                               public void run() {
-                                                       asyncRefresh();
-                                               }
-                                       });
-                               } catch (SWTException e) {
-                                       stopLogTab(false);
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Processes a new Message.
-        * <p/>
-        * This adds the new message to the buffer, and gives it to the existing
-        * filters.
-        *
-        * @param newMessage
-        */
-       private void processNewMessage(LogMessage newMessage) {
-
-               // compute the index where the message goes.
-               // was the buffer empty?
-               int messageIndex = -1;
-               if (indexStart == -1) {
-                       indexStart = 0;
-                       messageIndex = indexStart;
-                       indexEnd = 1;
-               } else {
-                       messageIndex = indexEnd;
-
-                       // check we aren't overwriting start
-                       if (indexEnd == indexStart) {
-                               indexStart = (indexStart + 1) % STRING_BUFFER_LENGTH;
-                       }
-
-                       // increment the next usable slot index
-                       indexEnd = (indexEnd + 1) % STRING_BUFFER_LENGTH;
-               }
-
-               LogMessage oldMessage = null;
-
-               // record the message that was there before
-               if (buffer[messageIndex] != null) {
-                       oldMessage = buffer[messageIndex];
-               }
-
-               // then add the new one
-               buffer[messageIndex] = newMessage;
-
-               addMessage(newMessage, oldMessage);
-       }
-
-       /**
-        * Refreshes the UI with new messages.
-        */
-       private void asyncRefresh() {
-               if (table.isDisposed() == false) {
-                       synchronized (buffer) {
-                               flush();
-//                             try {
-//                                     // the circular buffer has been updated, let
-//                                     // have the filter flush
-//                                     // their display with the new messages.
-//                                     flush();
-//
-//                             } finally {
-//                                     // the pending refresh is done.
-//                                     pendingAsyncRefresh = false;
-//                             }
-                       }
-               } else {
-                       stopLogTab(true);
-               }
-       }
-
-       public void resetUI(boolean inUiThread) {
-
-               // the ui is static we just empty it.
-               if (table.isDisposed() == false) {
-                       if (inUiThread) {
-                               table.removeAll();
-                       } else {
-                               Display d = table.getDisplay();
-
-                               // run sync as we need to update right now.
-                               d.syncExec(new Runnable() {
-                                       @Override
-                                       public void run() {
-                                               if (table.isDisposed() == false) {
-                                                       table.removeAll();
-                                               }
-                                       }
-                               });
-                       }
-               }
-       }
-
-       public void setLevelIcon(Action[] icons) {
-               for (int i = 0; i < 5; i++) {
-                       int a = levelMode & (0x1 << i);
-                       icons[i].setChecked(a == (int) Math.pow(2, i));
-               }
-       }
-
-       public void initTab() {
-
-               // is it empty
-               if (uiReady() == false) {
-                       return;
-               }
-
-               msgClear();
-
-               if (indexStart != -1) {
-                       int max = indexEnd;
-                       if (indexEnd < indexStart) {
-                               max += STRING_BUFFER_LENGTH;
-                       }
-
-                       for (int i = indexStart; i < max; i++) {
-                               int realItemIndex = i % STRING_BUFFER_LENGTH;
-
-                               addMessage(buffer[realItemIndex], null /** old message*/);
-                       }
-               }
-
-               flush();
-       }
-
-       public void refill() {
-               msgClear();
-
-               synchronized (buffer) {
-                       for (LogMessage logMsg : buffer) {
-                               if (accept(logMsg)) {
-                                       addMessage(logMsg, null);
-                               }
-                       }
-               }
-               flush();
-       }
-
-       public void tableRefill(int index, String filter) {
-
-               filterKeywordFromPanel = filter;
-               filterIndexFromPanel = index;
-
-               msgClear();
-
-               synchronized (buffer) {
-                       for (LogMessage logMsg : buffer) {
-                               if (accept(logMsg) && tableAccept(logMsg)) {
-                                       addMessage(logMsg, null);
-                               }
-                       }
-               }
-               flush();
-       }
-
-       public int getFilterIndexFromPanel()
-       {
-               return filterIndexFromPanel;
-       }
-
-       public void setFilterIndexFromPanel(int index)
-       {
-               filterIndexFromPanel = index;
-       }
-
-       public String getFilterKeywordFromPanel()
-       {
-               return filterKeywordFromPanel;
-       }
-
-       public void setFilterKeywordFromPanel(String keyword)
-       {
-               filterKeywordFromPanel = keyword;
-       }
-
-       boolean tableAccept(LogMessage logMessage) {
-               if (logMessage == null)
-                       return false;
-
-               if (filterKeywordFromPanel == null || filterKeywordFromPanel.length() == 0)
-                       return true;
-
-               switch(filterIndexFromPanel) {
-               case 0:
-                       {
-                               String[] filter = filterKeywordFromPanel.split("[\\s\t,]");
-                               for (int i = 0; i < filter.length; i++) {
-                                       if (logMessage.data.pidString.contains(
-                                                       filter[i]))
-                                               return true;
-                               }
-                       }
-                       break;
-
-               case 1:
-                       {
-                               String[] filter = filterKeywordFromPanel.split("[\\s\t,]");
-                               for (int i = 0; i < filter.length; i++) {
-                                       if (logMessage.data.tag.toLowerCase().contains(
-                                                       filter[i].toLowerCase()))
-                                               return true;
-                               }
-                       }
-                       break;
-
-               case 2:
-                       {
-                               String[] filter = filterKeywordFromPanel.split("[\\s\t,]");
-                               for (int i = 0; i < filter.length; i++) {
-                                       if (logMessage.msg.toLowerCase().contains(
-                                                       filter[i].toLowerCase()))
-                                               return true;
-                               }
-                       }
-                       break;
-
-               default:
-                       return false;
-
-               }
-               return false;
-       }
-
-       public void setLevel(int level, boolean setLevel) {
-               level = (int) Math.pow(2, level);
-               if (setLevel)
-                       levelMode |= level;
-               else
-                       levelMode &= (~level);
-       }
-
-       //remove all filtered messages and tableMessages  for refill or init tab
-       public void msgClear() {
-               removedMessageCount = 0;
-               newMessages.clear();
-               lastMessageInfo = null;
-               tableMessages.clear();
-               if (table.isDisposed() == false)
-                       table.removeAll();
-       }
-
-       //buffer clear
-       public void clear() {
-               for (int i = 0; i < STRING_BUFFER_LENGTH; i++) {
-                       buffer[i] = null;
-               }
-
-               indexStart = -1;
-               indexEnd = -1;
-
-               msgClear();
-       }
-
-       public void setDevice(IDevice device) {
-               filterDevice = device;
-       }
-
-       public void setDefault() {
-               isDefault = true;
-       }
-
-       public boolean isDefault() {
-               return isDefault;
-       }
-
-       public void setPendingAsyncRefresh(boolean b)
-       {
-               pendingAsyncRefresh = b;
-       }
-
+public class LogTab
+{
+
+    private static final int STRING_BUFFER_LENGTH = 5000;
+
+    public static final int FILTER_NONE = -1;
+    public static final int FILTER_PID = 0;
+    public static final int FILTER_TAG = 1;
+    public static final int FILTER_MESSAGE = 2;
+
+    public static final int LEVEL_ALL = 0x1F;
+    
+    private int levelMode = LEVEL_ALL;
+
+    //words to filter
+    private String[] pidFilters = null;
+    private String[] tagFilters = null;
+    private String[] msgFilters = null;
+
+    //need to show previous input value when tab dialog is opened
+    private String pidInput = null;
+    private String tagInput = null;
+    private String msgInput = null;
+
+    private int filterCombo = FILTER_MESSAGE;
+    private String filterText = "";
+
+    private String logTabName = null;
+    private IDevice device = null;
+    private LogTabOuputReceiver logReceiver = null;
+    private LogColors colors;
+
+    private Table table;
+    private TabItem tabItem;
+
+    private boolean isScrollLocked;
+
+    private static Pattern logPattern = Pattern.compile("^\\[\\s(\\d\\d-\\d\\d\\s\\d\\d:\\d\\d:\\d\\d\\.\\d+)"
+    + "\\s+(\\d*):\\s*(\\d+)\\s([VDIWE])/(.+)\\s+\\]$");
+
+    //Array to keep all messages from device
+    private final LogMessage[] allMessages = new LogMessage[STRING_BUFFER_LENGTH];
+
+    //List about filtered messages with pidFilters, tagFilters, msgFilters
+    private final List<LogMessage> filteredMessages = new ArrayList<LogMessage>();
+
+    //List about messages need to added table contents
+    private final List<LogMessage> newMessages = new ArrayList<LogMessage>();
+
+    private LogMessageInfo lastMessageInfo = null;
+
+    private boolean isDefault = false;
+
+    //index for allMessages
+    private int indexStart = -1;
+    private int indexEnd = -1;
+
+    public LogTab(String pName, IDevice pDevice, LogColors pColors)
+    {
+        logTabName = pName;
+        device = pDevice;
+        this.colors = pColors;
+    }
+
+    public LogTab()
+    {
+    }
+
+    public void setLogTabName(String name)
+    {
+        logTabName = name;
+    }
+
+    /**
+     * Get logTab name
+     * @return String
+     */
+    public String getLogTabName()
+    {
+        return logTabName;
+    }
+
+    public void setPidFilter(String pid)
+    {
+        pidInput = pid;
+        if (pid != null)
+            pidFilters = setFilter(pid.split("[\\s\t,]"));
+        else
+            pidFilters = null;
+    }
+
+    public void setTagFilter(String tag)
+    {
+        tagInput = tag;
+        if (tag != null)
+            tagFilters = setFilter(tag.split("[\\s\t,]"));
+        else
+            tagFilters = null;
+    }
+
+    public void setMsgFilter(String msg)
+    {
+        msgInput = msg;
+        if (msg != null)
+            msgFilters = setFilter(msg.split("[\\s\t,]"));
+        else
+            msgFilters = null;
+    }
+
+    private String[] setFilter(String[] array)
+    {
+        ArrayList<String> result = new ArrayList<String>();
+        for (String s : array)
+        {
+            if (s.length() > 0)
+            {
+                result.add(s);
+            }
+        }
+        return result.toArray(new String[(result.size())]);
+    }
+
+    public void setLevelMode(int level)
+    {
+        levelMode = level;
+    }
+
+    public int getLevelMode()
+    {
+        return levelMode;
+    }
+
+    public String getPidFilter()
+    {
+        return pidInput;
+    }
+
+    public String getTagFilter()
+    {
+        return tagInput;
+    }
+
+    public String getMsgFilter()
+    {
+        return msgInput;
+    }
+
+    public String getDeviceSerialNumber()
+    {
+        if (device != null)
+            return device.getSerialNumber();
+        else
+            return null;
+    }
+
+    public void setTabItem(TabItem tabItem)
+    {
+        this.tabItem = tabItem;
+    }
+
+    public TabItem getTabItem()
+    {
+        return tabItem;
+    }
+
+    public void setTable(Table table)
+    {
+        this.table = table;
+    }
+
+    /**
+     * Returns the UI table object.
+     *
+     * @return
+     */
+    public Table getTable()
+    {
+        return table;
+    }
+
+    public void start()
+    {
+
+        if (device != null)
+        {
+            // create a new output receiver
+            logReceiver = new LogTabOuputReceiver();
+
+            // start the LogTab in a different thread
+            new Thread(device.getSerialNumber() + " Logger") { //$NON-NLS-1$
+                @Override
+                public void run()
+                {
+                    while (device.isOnline() == false && logReceiver != null && logReceiver.isCancelled == false)
+                    {
+                        try
+                        {
+                            sleep(2000);
+                        } catch (InterruptedException e)
+                        {
+                            Logger.error("LogTab : Device is not online or logger is null/cancelled", e.getMessage(), e);
+                            return;
+                        }
+                    }
+
+                    if (logReceiver == null || logReceiver.isCancelled)
+                    {
+                        return;
+                    }
+
+                    try
+                    {
+                        device.executeShellCommand("dlogutil -v long *:v", logReceiver, 0 /* timeout */); //$NON-NLS-1$
+                    } catch (Exception e)
+                    {
+                        Logger.error("LogTab", e);
+                    }
+                }
+            }.start();
+        }
+    }
+
+    /** Stop the current LogTab */
+    public void stop(boolean inUiThread)
+    {
+        if (logReceiver != null)
+        {
+            logReceiver.isCancelled = true;
+
+            logReceiver = null;
+
+            device = null;
+
+            clear();
+
+        }
+    }
+
+    // add message to filtered message and replace old message to
+    // new message
+    public void addFilteredMessage(LogMessage newMessage, LogMessage oldMessage)
+    {
+        synchronized (filteredMessages)
+        {
+            if (oldMessage != null && filteredMessages.size() >= STRING_BUFFER_LENGTH)
+            {
+                int index = filteredMessages.indexOf(oldMessage);
+                if (index != -1)
+                {
+                    filteredMessages.remove(index);
+                }
+            }
+
+            boolean isValid = filteredByFilterString(newMessage);
+
+            if (isValid)
+            {
+                filteredMessages.add(newMessage);
+                if(filteredByIconAndText(newMessage))
+                    newMessages.add(newMessage);
+            }
+        }
+    }
+
+    /**
+     * action when select level icon and input combo and text to TabItem bottom
+     */
+    public void filterMessages()
+    {
+        //1. remove table contents
+        initialize();
+        //2. filtering
+        synchronized (filteredMessages)
+        {
+            for (LogMessage logMsg : filteredMessages)
+            {
+                if (filteredByIconAndText(logMsg))
+                {
+                    newMessages.add(logMsg);
+                }
+            }
+            //3. refill new messages
+            flush();
+        }
+    }
+
+    /**
+     * Filter with tab dialog(AddTab, EditTab) input value
+     * @param logMessage
+     * @return
+     */
+    private boolean filteredByFilterString(LogMessage logMessage)
+    {
+        if (logMessage == null)
+            return false;
+        if (pidFilters != null || tagFilters != null || msgFilters != null)
+        {
+            if (pidFilters != null)
+            {
+                for (String filter : pidFilters)
+                {
+                    if (logMessage.data.pidString.contains(filter))
+                        return true;
+                }
+            }
+
+            if (tagFilters != null)
+            {
+                for (String filter : tagFilters)
+                {
+                    if (logMessage.data.tag.toLowerCase().contains(filter.toLowerCase()))
+                        return true;
+                }
+            }
+
+            if (msgFilters != null)
+            {
+                for (String filter : msgFilters)
+                {
+                    if (logMessage.msg.toLowerCase().contains(filter.toLowerCase()))
+                        return true;
+                }
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Filter with level icon on LogView toolbar
+     * @param logMessage
+     * @return
+     */
+    boolean filteredByIconAndText(LogMessage logMessage)
+    {
+        if (logMessage == null)
+            return false;
+
+        if (levelMode != LEVEL_ALL)
+        {
+            int a = 0;
+            a = (levelMode & (0x1 << (logMessage.data.logLevel.getPriority() - 2)));
+
+            if (a == 0)
+                return false;
+        }
+
+        if (filteredByText(logMessage))
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * Filter with text and combo input from TabItem bottom
+     * @param logMessage
+     * @return
+     */
+    boolean filteredByText(LogMessage logMessage)
+    {
+        if (logMessage == null)
+        {
+            return false;
+        }
+
+        if (StringUtil.isEmpty(filterText))
+        {
+            return true;
+        }
+
+        String msg = null;
+        String filter = filterText.toLowerCase();
+
+        switch (filterCombo)
+        {
+            case FILTER_PID:
+                msg = logMessage.data.pidString;
+                break;
+    
+            case FILTER_TAG:
+                msg = logMessage.data.tag.toLowerCase();
+                break;
+    
+            case FILTER_MESSAGE:
+                msg = logMessage.msg.toLowerCase();
+                break;
+    
+            default:
+                return false;
+        }
+
+        if( msg.contains(filter))
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * flush valid messages to table and remove
+     */
+    public void flush()
+    {
+        table.setRedraw(false);
+
+        int newCount = newMessages.size();
+
+        try
+        {
+            int totalCount = table.getItemCount() + newCount;
+            if(totalCount > STRING_BUFFER_LENGTH)
+            {
+                int removeCount = totalCount - STRING_BUFFER_LENGTH;
+                //remove over than STRING_BUFFER_LENGTH
+                for (int i = 0; i < removeCount && table.getItemCount() > 0; i++)
+                {
+                    table.remove(0);
+                }
+            }
+            // add the new items
+            for (int i = 0; i < newCount; i++)
+            {
+                LogMessage msg = newMessages.get(i);
+                addTableItem(msg);
+            }
+        } catch (SWTException e)
+        {
+            Logger.error("LogFilter", e);
+        }
+
+        //if isScollLocked is false,  always shows last table item 
+        if(!getScrollLock())
+        {
+            int count = table.getItemCount();
+            if( count > 1)
+            {
+                table.showItem(table.getItem(table.getItemCount() - 1));
+            }
+        }
+
+        table.setRedraw(true);
+
+        newMessages.clear();
+
+    }
+
+    void setColors(LogColors pColors)
+    {
+        colors = pColors;
+    }
+
+    /**
+     * Add a TableItem for the index-th item of the buffer
+     *
+     * @param filter
+     *            The index of the table in which to insert the item.
+     */
+    private void addTableItem(LogMessage msg)
+    {
+        TableItem item = new TableItem(table, SWT.NONE);
+        item.setText(0, msg.data.time);
+        item.setText(2, msg.data.pidString);
+        item.setText(3, msg.data.tag);
+        item.setText(4, msg.msg);
+
+        // add the buffer index as data
+        item.setData(msg);
+
+        if (msg.data.logLevel == LogLevel.INFO)
+        {
+            item.setForeground(colors.infoColor);
+            item.setText(1, "Info");
+        } else if (msg.data.logLevel == LogLevel.DEBUG)
+        {
+            item.setForeground(colors.debugColor);
+            item.setText(1, "Debug");
+        } else if (msg.data.logLevel == LogLevel.ERROR)
+        {
+            item.setForeground(colors.errorColor);
+            item.setText(1, "Error");
+        } else if (msg.data.logLevel == LogLevel.WARN)
+        {
+            item.setForeground(colors.warningColor);
+            item.setText(1, "Warning");
+        } else if (msg.data.logLevel == LogLevel.VERBOSE)
+        {
+            item.setForeground(colors.verboseColor);
+            item.setText(1, "Verbose");
+        }
+    }
+
+    /**
+     * objects able to receive the output of a remote shell command,
+     * specifically a LogTab command in this case
+     */
+    private final class LogTabOuputReceiver extends MultiLineReceiver
+    {
+
+        public boolean isCancelled = false;
+
+        public LogTabOuputReceiver()
+        {
+            super();
+
+            setTrimLine(false);
+        }
+
+        @Override
+        public void processNewLines(String[] lines)
+        {
+            if (isCancelled == false)
+            {
+                processLogLines(lines);
+            }
+        }
+
+        @Override
+        public boolean isCancelled()
+        {
+            return isCancelled;
+        }
+    }
+
+    /**
+     * Process new Log lines coming from {@link LogCatOuputReceiver}.
+     *
+     * @param lines
+     *            the new lines
+     */
+    protected void processLogLines(String[] lines)
+    {
+        // WARNING: this will not work if the string contains more line
+        // than the buffer holds.
+
+        if (lines.length > STRING_BUFFER_LENGTH)
+        {
+            Logger.error("LogTab : Receiving more lines than " + STRING_BUFFER_LENGTH, "");
+            return ;
+        }
+
+        // parse the lines and create LogMessage that are stored in a temporary
+        // list
+        final ArrayList<LogMessage> newMessages = new ArrayList<LogMessage>();
+
+        synchronized (allMessages)
+        {
+            for (String line : lines)
+            {
+                line = AnsicodeAdapter.getStripAnsiString(line);
+                // ignore empty lines.
+                if (line.length() > 0)
+                {
+                    // check for header lines.
+                    Matcher matcher = logPattern.matcher(line);
+                    if (matcher.matches())
+                    {
+                        // this is a header line, parse the header and keep it
+                        // around.
+                        lastMessageInfo = new LogMessageInfo();
+
+                        lastMessageInfo.time = matcher.group(1);
+                        lastMessageInfo.pidString = matcher.group(2);
+                        lastMessageInfo.logLevel = LogLevel.getByLetterString(matcher.group(4));
+                        lastMessageInfo.tag = matcher.group(5).trim();
+                    } else
+                    {
+
+                        if (lastMessageInfo == null)
+                        {
+                            return;
+                        }
+
+                        // This is not a header line.
+                        // Create a new LogMessage and process it.
+                        LogMessage mc = new LogMessage();
+
+                        // If someone printed a log message with embedded '\n'
+                        // characters,
+                        // there will one header line followed by multiple text
+                        // lines.
+                        // Use the last header that we saw.
+                        mc.data = lastMessageInfo;
+
+                        // tabs seem to display as only 1 tab so we replace the
+                        // leading tabs by 4 spaces.
+                        mc.msg = line.replaceAll("\t", "    "); //$NON-NLS-1$ //$NON-NLS-2$
+
+                        // process the new LogMessage.
+                        processNewMessage(mc);
+
+                        // store the new LogMessage
+                        newMessages.add(mc);
+                    }
+                }
+            }
+
+            try
+            {
+                Display display = table.getDisplay();
+
+                // run in sync because this will update the
+                // buffer start/end indices
+                display.asyncExec(new Runnable()
+                {
+                    @Override
+                    public void run()
+                    {
+                        asyncRefresh();
+                    }
+                });
+            } catch (SWTException e)
+            {
+                // display is disposed, stop the LogTab
+                stop(false);
+            }
+        }
+    }
+
+    /**
+     * Processes a new Message.
+     * <p/>
+     * This adds the new message to the buffer, and gives it to the existing
+     * filters.
+     *
+     * @param newMessage
+     */
+    private void processNewMessage(LogMessage newMessage)
+    {
+
+        // compute the index where the message goes.
+        // was the buffer empty?
+        int messageIndex = -1;
+        if (indexStart == -1)
+        {
+            indexStart = 0;
+            messageIndex = indexStart;
+            indexEnd = 1;
+        } else
+        {
+            messageIndex = indexEnd;
+
+            // check we aren't overwriting start
+            if (indexEnd == indexStart)
+            {
+                indexStart = (indexStart + 1) % STRING_BUFFER_LENGTH;
+            }
+
+            // increment the next usable slot index
+            indexEnd = (indexEnd + 1) % STRING_BUFFER_LENGTH;
+        }
+
+        LogMessage oldMessage = null;
+
+        // record the message that was there before
+        if (allMessages[messageIndex] != null)
+        {
+            oldMessage = allMessages[messageIndex];
+        }
+
+        // then add the new one
+        allMessages[messageIndex] = newMessage;
+
+        addFilteredMessage(newMessage, oldMessage);
+    }
+
+    /**
+     * Refreshes the UI with new messages.
+     */
+    private void asyncRefresh()
+    {
+        if (table.isDisposed() == false)
+        {
+            synchronized (allMessages)
+            {
+                flush();
+            }
+        } else
+        {
+            stop(true);
+        }
+    }
+
+    public void resetUI(boolean inUiThread)
+    {
+
+        // the ui is static we just empty it.
+        if (table.isDisposed() == false)
+        {
+            if (inUiThread)
+            {
+                table.removeAll();
+            } else
+            {
+                Display d = table.getDisplay();
+
+                // run sync as we need to update right now.
+                d.syncExec(new Runnable()
+                {
+                    @Override
+                    public void run()
+                    {
+                        if (table.isDisposed() == false)
+                        {
+                            table.removeAll();
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+
+    public void setFilterCombo(int index)
+    {
+        filterCombo = index;
+    }
+
+    public void setFilterText(String text)
+    {
+        filterText = text;
+    }
+
+    // remove all filtered messages and tableMessages to refill or fill messages
+    public void initialize()
+    {
+        newMessages.clear();
+        lastMessageInfo = null;
+        resetUI(false);
+    }
+
+    // buffer and messages clear
+    public void clear()
+    {
+        synchronized(allMessages)
+        {
+            for (int i = 0; i < STRING_BUFFER_LENGTH; i++)
+            {
+                allMessages[i] = null;
+            }
+        }
+
+        indexStart = -1;
+        indexEnd = -1;
+        filteredMessages.clear();
+        initialize();
+    }
+
+    public void setDevice(IDevice device)
+    {
+        this.device = device;
+    }
+
+    public void setDefault()
+    {
+        isDefault = true;
+    }
+
+    public boolean isDefault()
+    {
+        return isDefault;
+    }
+
+    public void setScrollLock(boolean islock)
+    {
+        isScrollLocked = islock;
+    }
+
+    public boolean getScrollLock()
+    {
+        return isScrollLocked;
+    }
 }
\ No newline at end of file
index 6f0ab47..973028f 100644 (file)
@@ -1,17 +1,17 @@
 Log = Log
 
-Log_Title_Tab_AddTab_Error = Add tab error
-Log_Title_Tab_EditTab_Error = Edit tab error
-Log_Title_View_Device_Disconnected = Device is disconnected
+Log_Title_Tab_AddTab_Error = Error in adding a tab
+Log_Title_Tab_EditTab_Error = Error in editing a tab
+Log_Title_View_Device_Disconnected = Device disconnected
 
 Log_Message_Tab_Device_Disconnected = %s tab's device is already disconnected.
 Log_Message_View_Device_Disconnected =  %s is disconnected.\nThe tabs for %s do not work.
-Log_Message_View_Filter_Text = Search Keywords from this table are separated by a space as well as a comma
+Log_Message_View_Filter_Text = Input search keyword
 
-Log_Tooltip_View_Filter_Combo = Keyword Search: Pid or Tag, Message
+Log_Tooltip_View_Filter_Combo = Keyword: Pid, Tag, or Message
 
-Log_Title_Tab_Export = Export Log
+Log_Title_Tab_Export = Export the log
 
 Log_File_Tab_Export_Postfix =  %s-log.txt
-Log_File_Tab_Export_Filter = Text Files (*.txt)
+Log_File_Tab_Export_Filter = Text files (*.txt)
 Log_File_Tab_Export_Filter_Extensions = *.txt
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 538a411..f286a6f
@@ -128,14 +128,10 @@ public class ConnectionExplorerPermissionPropertyPages extends PropertyPage {
                table.setHeaderVisible(true);
                table.setLinesVisible(true);
                
-               TableColumn colMsg = createTableColumn(table, "", SWT.NONE,
-               "EXECUTE");
-               colMsg = createTableColumn(table, "Read", SWT.NONE,
-               "EXECUTE");
-               colMsg = createTableColumn(table, "Write", SWT.NONE,
-               "EXECUTE");
-               colMsg = createTableColumn(table, "Execute", SWT.NONE,
-               "EXECUTE");
+               createTableColumn(table, "", SWT.NONE, "EXECUTE");
+               createTableColumn(table, "Read", SWT.NONE, "EXECUTE");
+               createTableColumn(table, "Write", SWT.NONE, "EXECUTE");
+               createTableColumn(table, "Execute", SWT.NONE, "EXECUTE");
                
                
                itemUser = new TableItem(table, SWT.NONE);
index 4b5084a..a67e03d 100644 (file)
@@ -3,10 +3,10 @@
 *
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
 *
-* Contact: 
+* Contact:
 * Hoon Kang <h245.kang@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
@@ -38,7 +38,6 @@ import org.eclipse.ui.part.IDropActionDelegate;
 import org.tizen.common.connection.ConnectionPlugin;
 import org.tizen.common.connection.ddmuilib.FileDialogUtils;
 import org.tizen.common.connection.ddmuilib.console.DdmConsole;
-
 import org.tizen.sdblib.SdbCommandRejectedException;
 import org.tizen.sdblib.SyncService;
 import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
@@ -50,22 +49,22 @@ public class FileEntryDropAdapter implements IDropActionDelegate {
        @Override
        public boolean run(Object source, Object target) {
                IResource resource = null;
-               
+
                if (target instanceof IAdaptable) {
                        target = ((IAdaptable) target).getAdapter(IResource.class);
                        if (target != null && target instanceof IResource) {
                                resource = (IResource) target;
                                if (resource.getType() == IResource.FILE && resource.getParent() != null)
-                                       resource = resource.getParent(); 
+                                       resource = resource.getParent();
                        }
                }
-       
+
                String[] entries = FileEntryTransfer.getInstance().fromByteArray(
                                (byte[]) source);
-               
-               if (entries.length < 1) 
+
+               if (entries.length < 1)
                        return false;
-               
+
                SyncService sync = null;
                try {
                        sync = ConnectionPlugin.getDefault().getCurrentDevice().getSyncService();
@@ -82,7 +81,7 @@ public class FileEntryDropAdapter implements IDropActionDelegate {
                if (sync != null) {
                        ISyncProgressMonitor monitor = SyncService.getNullProgressMonitor();
                        boolean isAlwayCopy = false;
-                       
+
                        for (int i = 0; i < entries.length; i++) {
                                File f = new File(entries[i]);
                                if (resource == null )
@@ -91,10 +90,10 @@ public class FileEntryDropAdapter implements IDropActionDelegate {
                                IResource newRes = resource.getWorkspace().getRoot().findMember(localPath);
 
                                String localFilePath = resource.getLocation().append(f.getName()).toOSString();
-                                 
+
                if (newRes != null) {
                                        if (isAlwayCopy == false) {
-                                               int ret = FileDialogUtils.getInstance().checkOverwrite(f.getName());
+                                               int ret = FileDialogUtils.checkOverwrite(f.getName());
                                                switch (ret) {
                                                        case IDialogConstants.CANCEL_ID :
                                                                return false;
@@ -104,7 +103,7 @@ public class FileEntryDropAdapter implements IDropActionDelegate {
                                                        case IDialogConstants.NO_ID :
                                                                continue;
                                                        default:
-                                               }                                                                       
+                                               }
                                        }
                                }
                                SyncResult result = sync.pullFile(entries[i], localFilePath     , monitor);
@@ -121,12 +120,12 @@ public class FileEntryDropAdapter implements IDropActionDelegate {
                                                } catch (CoreException e) {
                                                        e.printStackTrace();
                                                }
-                                       }               
+                                       }
                                }
                        }
                }
 
        return false;
        }
-       
+
 }
old mode 100644 (file)
new mode 100755 (executable)
index a572d5c..f542b3d
@@ -1,28 +1,28 @@
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* Hoon Kang <h245.kang@samsung.com>
-* Hyunsik Noh <hyunsik.noh@samsung.com>
-* 
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hoon Kang <h245.kang@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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
-*
-*/
+ * 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.common.connection.ui;
 
 import java.io.File;
@@ -45,365 +45,446 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.contexts.IContextService;
-import org.eclipse.ui.dialogs.PropertyDialogAction;
 import org.eclipse.ui.part.ViewPart;
+import org.tizen.common.TizenHelpContextIds;
 import org.tizen.common.connection.ConnectionPlugin;
-import org.tizen.common.connection.ddmuilib.ImageLoader;
 import org.tizen.common.connection.explorer.ConnectionExplorerPanel;
-import org.tizen.common.properties.InstallPathConfig;
+import org.tizen.common.core.application.InstallPathConfig;
 import org.tizen.common.util.HostUtil;
 
-
-public class ConnectionExplorer extends ViewPart {
-
-       private ConnectionExplorerPanel panel;
-       private ImageLoader mloader;
-       private ToolBar mToolBar;
-
-       private ToolItem pushToolItem;
-       private ToolItem pullToolItem;
-       private ToolItem emulStartToolItem;
-
-       private MenuManager subMenu;
-       private Action actionAddFolder;
-       private Action actionAddFile;
-       private Action actionPush;
-       private Action actionPull;
-       private Action actionRefresh;
-       private Action actionRename;
-       private Action actionProperty;
-       private Action actionDelete;
-
-       private MenuManager menuMgr;
-       private static ConnectionExplorer explorer;
-
-       private static final String BINARYMESSAGE = "Emulator is not installed or install path is not valid.";
-       private static final String EMULATOR_PATH = InstallPathConfig
-                       .getEmulatorPath();
-       private static final String EMULATOR_BATCH = "bin" + File.separatorChar + "emulator-manager.exe";
-       private static final String EMULATOR_BINARY = "bin" + File.separatorChar + "emulator-manager";
-
-       public static ConnectionExplorer gerDefault() {
-               if (explorer == null) {
-                       explorer = new ConnectionExplorer();
-               }
-
-               return explorer;
-       }
-
-       @Override
-       public void createPartControl(Composite parent) {
-               mloader = ImageLoader.getDdmUiLibLoader();
-
-               parent.setLayoutData(new GridData(GridData.FILL_VERTICAL));
-               parent.setLayout(new GridLayout(1, false));
-
-               Composite top = new Composite(parent, SWT.NONE);
-
-               GridLayout gridLayout = new GridLayout();
-               gridLayout.numColumns = 3;
-               gridLayout.marginWidth = 0;
-               gridLayout.marginHeight = 0;
-
-               GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
-               gridData.horizontalSpan = 2;
-
-               top.setLayoutData(gridData);
-               top.setLayout(gridLayout);
-
-               createToolBar(top, gridData);
-
-               Composite bottom = new Composite(parent, SWT.NONE);
-               bottom.setLayoutData(new GridData(GridData.FILL_BOTH));
-               bottom.setLayout(new FillLayout());
-
-               createFileExplorerView(bottom);
-               makeActions();
-               activateContext();
-               initContextMenu();
-               
-               panel.setToolItems(pushToolItem, pullToolItem, emulStartToolItem);
-               
-               panel.setActions(subMenu, actionPush,
-                               actionPull, actionRefresh, actionRename, actionProperty,
-                               actionDelete);
-       }
-       private void createFileExplorerView(Composite parent) {
-
-               // device explorer
-               panel = new ConnectionExplorerPanel();
-               panel.createPanel(parent);
-               panel.getTreeViewer().getTree().addKeyListener(new KeyAdapter() {
-                       public void keyPressed(KeyEvent e) {
-                               handleKeyPressed(e);
-                       }
-                       public void keyReleased(KeyEvent e) {
-                               handleKeyPressed(e);
-                       }
-               });
-
-       }
-       private void handleKeyPressed(KeyEvent event) {
-
-               if (event.keyCode == SWT.F5) {
-                       actionRefresh();
-               } else if (event.keyCode == SWT.F2) {
-                       actionRename();
-               } else if (event.keyCode == SWT.DEL) {
-                       actionDelete();
-               }
-               if ((event.stateMask == SWT.ALT) && (event.keyCode == SWT.CR)) {
-                       actionShowProperty();
-               }
-       }
-       private void actionAddFile() {
-
-               panel.addNewFileSelection();
-       }
-
-       private void actionAddFolder() {
-               panel.addNewFolderSelection();
-       }
-
-       private void actionPush() {
-               panel.pushIntoSelection();
-       }
-
-       private void actionPull() {
-               panel.pullSelection();
-       }
-
-       private void actionRefresh() {
-               panel.refreshSelection();
-       }
-       private void actionDelete() {
-               panel.deleteSelection();
-       }
-       private void actionRename() {
-               panel.renameSelection();
-       }
-       private void actionShowProperty() {
-               PropertyDialogAction pda = new PropertyDialogAction(getSite(),
-                               panel.getTreeViewer());
-               pda.run();
-       }
-       /*
-        * make actions
-        */
-       private void makeActions() {
-               subMenu = new MenuManager("Add New..", null);
-
-               actionAddFile = new Action() {
-                       public void run() {
-                               actionAddFile();
-                       }
-               };
-               actionAddFile.setText("Add File");
-
-               actionAddFolder = new Action() {
-                       public void run() {
-                               actionAddFolder();
-                       }
-               };
-               actionAddFolder.setText("Add Folder");
-
-               actionPush = new Action() {
-                       public void run() {
-                               actionPush();
-                       }
-               };
-               actionPush.setText("Push the file");
-
-               actionPull = new Action() {
-                       public void run() {
-                               actionPull();
-                       }
-               };
-               actionPull.setText("Pull the Selection");
-
-               // Add refresh action
-               actionRefresh = new Action() {
-                       public void run() {
-                               actionRefresh();
-                       }
-               };
-               actionRefresh.setText("Refresh");
-               actionRefresh
-                               .setActionDefinitionId("org.tizen.common.connection.refresh");
-
-               actionRename = new Action() {
-                       public void run() {
-                               actionRename();
-                       }
-               };
-
-               actionRename.setText("Rename");
-               actionRename
-                               .setActionDefinitionId("org.tizen.common.connection.rename");
-
-               actionDelete = new Action() {
-                       public void run() {
-                               actionDelete();
-                       }
-               };
-               actionDelete.setText("Delete");
-               actionDelete
-                               .setActionDefinitionId("org.tizen.common.connection.delete");
-
-               actionProperty = new PropertyDialogAction(getSite(),
-                               panel.getTreeViewer());
-               actionProperty
-                               .setActionDefinitionId("org.tizen.common.connection.property");
-
-       }
-       private void initContextMenu() {
-               // initalize the context menu
-               menuMgr = new MenuManager("Connection Explorer MenuMgr"); //$NON-NLS-1$
-               menuMgr.setRemoveAllWhenShown(true);
-               menuMgr.addMenuListener(new IMenuListener() {
-
-                       @Override
-                       public void menuAboutToShow(IMenuManager manager) {
-                               fillContextMenu(manager);
-                       }
-               });
-
-               Menu menu = menuMgr.createContextMenu(panel.getTreeViewer().getTree());
-               panel.getTreeViewer().getTree().setMenu(menu);
-               getSite().registerContextMenu(menuMgr, panel.getTreeViewer());
-
-               menuMgr.addMenuListener(new IMenuListener() {
-                       @Override
-                       public void menuAboutToShow(IMenuManager manager) {
-                               // Remove team menu from our menu
-                               IContributionItem[] items = manager.getItems();
-                               if (items != null) {
-                                       for (int i = 0; i < items.length; i++) {
-                                               IContributionItem item = items[i];
-                                               if (item.getId() != null) {
-                                                       if (item.getId().equals("team.main")) {
-                                                               manager.remove(item);
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                               }
-                               // Decide whether to enable/disable actions
-                               panel.setActionState();
-                       }
-               });
-       }
-
-       private void activateContext() {
-
-               IContextService contextService = (IContextService) getSite()
-                               .getService(IContextService.class);
-               contextService
-                               .activateContext("org.tizen.common.connection.delete.context");
-               contextService
-                               .activateContext("org.tizen.common.connection.rename.context");
-               contextService
-                               .activateContext("org.tizen.common.connection.refresh.context");
-               contextService
-                               .activateContext("org.tizen.common.connection.property.context");
-
-       }
-       private void fillContextMenu(IMenuManager manager) {
-               subMenu.add(actionAddFile);
-               subMenu.add(actionAddFolder);
-               manager.add(subMenu);
-               manager.add(new Separator());
-               manager.add(actionPush);
-               manager.add(actionPull);
-               manager.add(new Separator());
-               manager.add(actionRefresh);
-               manager.add(new Separator());
-               manager.add(actionRename);
-               manager.add(actionDelete);
-               manager.add(new Separator());
-               manager.add(actionProperty);
-               manager.add(new Separator());
-       }
-
-       private void createToolBar(Composite shell, Object layoutData) {
-
-               mToolBar = new ToolBar(shell, SWT.NULL);
-               mToolBar.setLayoutData(layoutData);
-
-               ToolItem item = new ToolItem(mToolBar, SWT.SEPARATOR);
-
-               emulStartToolItem = new ToolItem(mToolBar, SWT.PUSH);
-               emulStartToolItem.setImage(mloader.loadImage("Emulator_start.gif",
-                               shell.getDisplay()));
-               emulStartToolItem.setToolTipText("Emulator Manager");
-               emulStartToolItem.addSelectionListener(new SelectionAdapter() {
-                       public void widgetSelected(SelectionEvent e) {
-                               try {
-                                       startEmulatorManager();
-                               } catch (Exception e1) {
-                                       e1.printStackTrace();
-                               }
-                       }
-               });
-               emulStartToolItem.setEnabled(true);
-
-               item = new ToolItem(mToolBar, SWT.SEPARATOR);
-
-               pushToolItem = new ToolItem(mToolBar, SWT.PUSH);
-               pushToolItem
-                               .setImage(mloader.loadImage("push.gif", shell.getDisplay()));
-               pushToolItem.setToolTipText("Push the files");
-               pushToolItem.addSelectionListener(new SelectionAdapter() {
-                       public void widgetSelected(SelectionEvent e) {
-                               panel.pushIntoSelection();
-                       }
-               });
-               pushToolItem.setEnabled(false);
-
-               item = new ToolItem(mToolBar, SWT.SEPARATOR);
-
-               pullToolItem = new ToolItem(mToolBar, SWT.PUSH);
-               pullToolItem
-                               .setImage(mloader.loadImage("pull.gif", shell.getDisplay()));
-               pullToolItem.setToolTipText("Pull the selection");
-               pullToolItem.addSelectionListener(new SelectionAdapter() {
-                       public void widgetSelected(SelectionEvent e) {
-                               panel.pullSelection();
-                       }
-               });
-               pullToolItem.setEnabled(false);
-               item = new ToolItem(mToolBar, SWT.SEPARATOR);
-
-       }
-
-       @Override
-       public void setFocus() {
-       }
-
-       private void startEmulatorManager() throws Exception {
-               String exePath = null;
-               int osType = ConnectionPlugin.getDefault().os;
-               int linuxType = ConnectionPlugin.getDefault().LINUX;
-
-               if (osType == linuxType) {
-                       exePath = EMULATOR_PATH + File.separatorChar + EMULATOR_BINARY;
-               } else {
-                       exePath = EMULATOR_PATH + File.separatorChar + EMULATOR_BATCH;
-               }
-
-               if (exePath.equals("") || (!exePath.equals("") && !HostUtil.exists(exePath))) {
-                       throw new Exception(BINARYMESSAGE);
-               }
-
-               // FIXME : should implement the lines below based on windows system.
-               String command = exePath;
-               if (osType == linuxType) {
-                       command = command + " 1>/dev/null 2>/dev/null &";
-
-                       HostUtil.execute(command);
-               } else {
-                       HostUtil.batchExecute(command, null, new File(EMULATOR_PATH));
-               }
-       }
+public class ConnectionExplorer extends ViewPart
+{
+
+    private ConnectionExplorerPanel panel;
+    private Composite parent;
+    
+    private ToolBar toolBar;
+
+    private ToolItem pushToolItem;
+    private ToolItem pullToolItem;
+    private ToolItem emulManagerToolItem;
+
+    private MenuManager subMenu;
+    private Action actionAddFolder;
+    private Action actionAddFile;
+    private Action actionPush;
+    private Action actionPull;
+    private Action actionRefresh;
+    private Action actionRename;
+    private Action actionProperty;
+    private Action actionDelete;
+
+    private MenuManager menuMgr;
+    private static ConnectionExplorer explorer;
+
+    private static final String EMULATOR_PATH = InstallPathConfig.getEmulatorPath();
+    private static final String EMULATOR_BATCH = "bin" + File.separatorChar + "emulator-manager.exe";
+    private static final String EMULATOR_BINARY = "bin" + File.separatorChar + "emulator-manager";
+
+    synchronized public static ConnectionExplorer gerDefault()
+    {
+        if (explorer == null)
+        {
+            explorer = new ConnectionExplorer();
+        }
+        return explorer;
+    }
+
+    synchronized public static void release() {
+        explorer = null;
+    }
+
+    @Override
+    public void dispose()
+    {
+    }
+
+    @Override
+    public void createPartControl(Composite p)
+    {
+        parent = p;
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, TizenHelpContextIds.HELP_COMMON_CONNECTION_EXPLORER_CONTEXT);
+        parent.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+        parent.setLayout(new GridLayout(1, false));
+
+        Composite top = new Composite(parent, SWT.NONE);
+
+        GridLayout gridLayout = new GridLayout();
+        gridLayout.numColumns = 3;
+        gridLayout.marginWidth = 0;
+        gridLayout.marginHeight = 0;
+
+        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+        gridData.horizontalSpan = 2;
+
+        top.setLayoutData(gridData);
+        top.setLayout(gridLayout);
+
+        createToolBar(top, gridData);
+
+        Composite bottom = new Composite(parent, SWT.NONE);
+        bottom.setLayoutData(new GridData(GridData.FILL_BOTH));
+        bottom.setLayout(new FillLayout());
+
+        createFileExplorerView(bottom);
+        makeActions();
+        activateContext();
+        initContextMenu();
+
+        panel.setToolItems(pushToolItem, pullToolItem, emulManagerToolItem);
+
+        panel.setActions(subMenu, actionPush, actionPull, actionRefresh, actionRename, actionProperty, actionDelete);
+    }
+
+    private void createFileExplorerView(Composite parent)
+    {
+
+        // device explorer
+        panel = new ConnectionExplorerPanel();
+        panel.createPanel(parent);
+        panel.getTreeViewer().getTree().addKeyListener(new KeyAdapter()
+        {
+            @Override
+            public void keyPressed(KeyEvent e)
+            {
+                handleKeyPressed(e);
+            }
+
+            @Override
+            public void keyReleased(KeyEvent e)
+            {
+            }
+        });
+
+    }
+
+    private void handleKeyPressed(KeyEvent event)
+    {
+
+        Tree tree = (Tree) event.widget;
+        int length = tree.getSelectionCount();
+        if (event.keyCode == SWT.F5)
+        {
+            if (length == 1)
+                actionRefresh();
+        } else if (event.keyCode == SWT.F2)
+        {
+            if (length == 1)
+                actionRename();
+        } else if (event.keyCode == SWT.DEL)
+        {
+            actionDelete();
+        }
+        if ((event.stateMask == SWT.ALT) && (event.keyCode == SWT.CR))
+        {
+            actionShowProperty();
+        }
+    }
+
+    private void actionAddFile()
+    {
+        panel.addNewFileSelection();
+    }
+
+    private void actionAddFolder()
+    {
+        panel.addNewFolderSelection();
+    }
+
+    private void actionPush()
+    {
+        panel.pushIntoSelection();
+    }
+
+    private void actionPull()
+    {
+        panel.pullSelection();
+    }
+
+    private void actionRefresh()
+    {
+        panel.refreshSelection();
+    }
+
+    private void actionDelete()
+    {
+        panel.deleteSelection();
+    }
+
+    private void actionRename()
+    {
+        panel.renameSelection();
+    }
+
+    private void actionShowProperty()
+    {
+        panel.showPropertySelection(getSite());
+    }
+
+    /*
+     * make actions
+     */
+    private void makeActions()
+    {
+        subMenu = new MenuManager(ConnectionUIMessages.Explorer_ConetextMenu_New, null);
+
+        actionAddFile = new Action()
+        {
+            @Override
+            public void run()
+            {
+                actionAddFile();
+            }
+        };
+        actionAddFile.setText(ConnectionUIMessages.Explorer_ConetextMenu_File);
+
+        actionAddFolder = new Action()
+        {
+            @Override
+            public void run()
+            {
+                actionAddFolder();
+            }
+        };
+        actionAddFolder.setText(ConnectionUIMessages.Explorer_ConetextMenu_Folder);
+
+        actionPush = new Action()
+        {
+            @Override
+            public void run()
+            {
+                actionPush();
+            }
+        };
+        actionPush.setText(ConnectionUIMessages.Explorer_ConetextMenu_Push);
+
+        actionPull = new Action()
+        {
+            @Override
+            public void run()
+            {
+                actionPull();
+            }
+        };
+        actionPull.setText(ConnectionUIMessages.Explorer_ConetextMenu_Pull);
+
+        // Add refresh action
+        actionRefresh = new Action()
+        {
+            @Override
+            public void run()
+            {
+                actionRefresh();
+            }
+        };
+        actionRefresh.setText(ConnectionUIMessages.Explorer_ConetextMenu_Refresh);
+        actionRefresh.setActionDefinitionId("org.tizen.common.connection.refresh");
+
+        actionRename = new Action()
+        {
+            @Override
+            public void run()
+            {
+                actionRename();
+            }
+        };
+
+        actionRename.setText(ConnectionUIMessages.Explorer_ConetextMenu_Rename);
+        actionRename.setActionDefinitionId("org.tizen.common.connection.rename");
+
+        actionDelete = new Action()
+        {
+            @Override
+            public void run()
+            {
+                actionDelete();
+            }
+        };
+        actionDelete.setText(ConnectionUIMessages.Explorer_ConetextMenu_Delete);
+        actionDelete.setActionDefinitionId("org.tizen.common.connection.delete");
+
+        actionProperty = new Action()
+        {
+            @Override
+            public void run()
+            {
+                panel.showPropertySelection(getSite());
+            }
+        };
+        actionProperty.setText(ConnectionUIMessages.Explorer_ConetextMenu_Property);
+        actionProperty.setActionDefinitionId("org.tizen.common.connection.property");
+
+    }
+
+    private void initContextMenu()
+    {
+        // initalize the context menu
+        menuMgr = new MenuManager("Connection Explorer MenuMgr"); //$NON-NLS-1$
+        menuMgr.setRemoveAllWhenShown(true);
+        menuMgr.addMenuListener(new IMenuListener()
+        {
+
+            @Override
+            public void menuAboutToShow(IMenuManager manager)
+            {
+                fillContextMenu(manager);
+            }
+        });
+
+        Menu menu = menuMgr.createContextMenu(panel.getTreeViewer().getTree());
+        panel.getTreeViewer().getTree().setMenu(menu);
+        getSite().registerContextMenu(menuMgr, panel.getTreeViewer());
+
+        menuMgr.addMenuListener(new IMenuListener()
+        {
+            @Override
+            public void menuAboutToShow(IMenuManager manager)
+            {
+                // Remove team menu from our menu
+                IContributionItem[] items = manager.getItems();
+                if (items != null)
+                {
+                    for (IContributionItem item : items)
+                    {
+                        if (("team.main").equals(item.getId()))
+                        {
+                            manager.remove(item);
+                            break;
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    private void activateContext()
+    {
+        IContextService contextService = (IContextService) getSite().getService(IContextService.class);
+        contextService.activateContext("org.tizen.common.connection.delete.context");
+        contextService.activateContext("org.tizen.common.connection.rename.context");
+        contextService.activateContext("org.tizen.common.connection.refresh.context");
+        contextService.activateContext("org.tizen.common.connection.property.context");
+
+    }
+
+    private void fillContextMenu(IMenuManager manager)
+    {
+        subMenu.add(actionAddFile);
+        subMenu.add(actionAddFolder);
+        manager.add(subMenu);
+        manager.add(new Separator());
+        manager.add(actionPush);
+        manager.add(actionPull);
+        manager.add(new Separator());
+        manager.add(actionRefresh);
+        manager.add(new Separator());
+        manager.add(actionRename);
+        manager.add(actionDelete);
+        manager.add(new Separator());
+        manager.add(actionProperty);
+        manager.add(new Separator());
+    }
+
+    private void createToolBar(Composite shell, Object layoutData)
+    {
+
+        toolBar = new ToolBar(shell, SWT.NULL);
+        toolBar.setLayoutData(layoutData);
+
+        new ToolItem(toolBar, SWT.SEPARATOR);   // Separator
+
+        emulManagerToolItem = new ToolItem(toolBar, SWT.PUSH);
+        emulManagerToolItem.setImage(ConnectionPlugin.getImageDescriptorFromPlugin("icons/emulator_manager.gif").createImage());
+        emulManagerToolItem.setToolTipText(ConnectionUIMessages.Explorer_Tooltip_EmulatorManager);
+        emulManagerToolItem.addSelectionListener(new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e)
+            {
+                try
+                {
+                    startEmulatorManager();
+                } catch (Exception e1)
+                {
+                    e1.printStackTrace();
+                }
+            }
+        });
+        emulManagerToolItem.setEnabled(true);
+
+        new ToolItem(toolBar, SWT.SEPARATOR);   // Separator
+
+        pushToolItem = new ToolItem(toolBar, SWT.PUSH);
+        pushToolItem.setImage(ConnectionPlugin.getImageDescriptorFromPlugin("icons/push.gif").createImage());
+        pushToolItem.setToolTipText(ConnectionUIMessages.Explorer_Tooltip_Push);
+        pushToolItem.addSelectionListener(new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e)
+            {
+                panel.pushIntoSelection();
+            }
+        });
+        pushToolItem.setEnabled(false);
+
+        new ToolItem(toolBar, SWT.SEPARATOR);   // Separator
+
+        pullToolItem = new ToolItem(toolBar, SWT.PUSH);
+        pullToolItem.setImage(ConnectionPlugin.getImageDescriptorFromPlugin("icons/pull.gif").createImage());
+        pullToolItem.setToolTipText(ConnectionUIMessages.Explorer_Tooltip_Pull);
+        pullToolItem.addSelectionListener(new SelectionAdapter()
+        {
+            @Override
+            public void widgetSelected(SelectionEvent e)
+            {
+                panel.pullSelection();
+            }
+        });
+        pullToolItem.setEnabled(false);
+        new ToolItem(toolBar, SWT.SEPARATOR);   // Separator
+    }
+
+    @Override
+    public void setFocus()
+    {
+        if(parent != null)
+        {
+            parent.setFocus();
+        }
+    }
+
+    private void startEmulatorManager() throws Exception
+    {
+        String exePath = null;
+        int osType = ConnectionPlugin.getDefault().os;
+        int linuxType = ConnectionPlugin.LINUX;
+
+        if (osType == linuxType)
+        {
+            exePath = EMULATOR_PATH + File.separatorChar + EMULATOR_BINARY;
+        } else
+        {
+            exePath = EMULATOR_PATH + File.separatorChar + EMULATOR_BATCH;
+        }
+
+        if (exePath.equals("") || (!exePath.equals("") && !HostUtil.exists(exePath)))
+        {
+            throw new Exception(ConnectionUIMessages.Explorer_Message_EmulatorError);
+        }
+
+        // FIXME : should implement the lines below based on windows system.
+        String command = exePath;
+        if (osType == linuxType)
+        {
+            command = command + " 1>/dev/null 2>/dev/null &";
+
+            HostUtil.execute(command);
+        } else
+        {
+            HostUtil.batchExecute(command, null, new File(EMULATOR_PATH));
+        }
+    }
 }
\ No newline at end of file
diff --git a/org.tizen.common.connection/src/org/tizen/common/connection/ui/ConnectionUIMessages.java b/org.tizen.common.connection/src/org/tizen/common/connection/ui/ConnectionUIMessages.java
new file mode 100644 (file)
index 0000000..b0c28b6
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Kangho Kim <kh5225.kim@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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.common.connection.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class ConnectionUIMessages extends NLS
+{
+    private static final String BUNDLE_NAME = ConnectionUIMessages.class.getPackage().getName() + ".ConnectionUIMessages"; //$NON-NLS-1$
+
+    public static String Explorer_ConetextMenu_New;
+    public static String Explorer_ConetextMenu_File;
+    public static String Explorer_ConetextMenu_Folder;
+    public static String Explorer_ConetextMenu_Push;
+    public static String Explorer_ConetextMenu_Pull;
+    public static String Explorer_ConetextMenu_Refresh;
+    public static String Explorer_ConetextMenu_Rename;
+    public static String Explorer_ConetextMenu_Delete;
+    public static String Explorer_ConetextMenu_Property;
+    
+    public static String Explorer_Message_Invalid_Character;
+
+    public static String Explorer_Tooltip_EmulatorManager;
+    public static String Explorer_Tooltip_Push;
+    public static String Explorer_Tooltip_Pull;
+
+    public static String Explorer_Message_EmulatorError;
+
+    static
+    {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, ConnectionUIMessages.class);
+    }
+
+    private ConnectionUIMessages()
+    {
+    }
+}
diff --git a/org.tizen.common.connection/src/org/tizen/common/connection/ui/ConnectionUIMessages.properties b/org.tizen.common.connection/src/org/tizen/common/connection/ui/ConnectionUIMessages.properties
new file mode 100644 (file)
index 0000000..056433f
--- /dev/null
@@ -0,0 +1,17 @@
+Explorer_ConetextMenu_New = New
+Explorer_ConetextMenu_File = File
+Explorer_ConetextMenu_Folder = Folder
+Explorer_ConetextMenu_Push = Push the file
+Explorer_ConetextMenu_Pull = Pull the selected content
+Explorer_ConetextMenu_Refresh = Refresh
+Explorer_ConetextMenu_Rename = Rename
+Explorer_ConetextMenu_Delete = Delete
+Explorer_ConetextMenu_Property = Properties
+
+Explorer_Tooltip_EmulatorManager = Emulator Manager
+Explorer_Tooltip_Push = Push the file to the connected target device
+Explorer_Tooltip_Pull = Pull the content from the connected target device
+
+Explorer_Message_Invalid_Character = File contains invalid characters like 
+
+Explorer_Message_EmulatorError = Emulator is not installed or the install path is invalid.
index a48f392..837bcd3 100644 (file)
@@ -1,28 +1,28 @@
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact:
-* Hoon Kang <h245.kang@samsung.com>
-* Hyunsik Noh <hyunsik.noh@samsung.com>
-*
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hoon Kang <h245.kang@samsung.com>
+ * Hyunsik Noh <hyunsik.noh@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
-*
-*/
+ * 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.common.connection.ui;
 
 import org.eclipse.jface.action.Action;
@@ -31,12 +31,13 @@ import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IToolBarManager;
 import org.eclipse.jface.action.Separator;
 import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.actions.ActionFactory;
 import org.eclipse.ui.part.ViewPart;
+import org.tizen.common.TizenHelpContextIds;
 import org.tizen.common.connection.ConnectionPlugin;
 import org.tizen.common.connection.log.LogColors;
 import org.tizen.common.connection.log.LogPanel;
@@ -46,184 +47,232 @@ import org.tizen.sdblib.Log.LogLevel;
  * The log cat view displays log output from the current device selection.
  *
  */
-public final class LogView extends ViewPart {
-
-       public static final String ID = "org.tizen.common.connection.ui.LogView"; //$NON-NLS-1$
-
-       private LogPanel logPanel;
-
-       private Action addAction;
-       private Action removeAction;
-       private Action editAction;
-       private Action exportAction;
-       private Action clearAction;
-
-       private Action[] logLevelActions;
-       private final String[] logLevelIcons = { "icons/log/v.png", //$NON-NLS-1S
-                       "icons/log/d.png", //$NON-NLS-1S
-                       "icons/log/i.png", //$NON-NLS-1S
-                       "icons/log/w.png", //$NON-NLS-1S
-                       "icons/log/e.png", //$NON-NLS-1S
-       };
-
-       private Clipboard clipboard;
-
-       @Override
-       public void createPartControl(Composite parent) {
-               Display d = parent.getDisplay();
-               LogColors colors = new LogColors();
-
-               colors.infoColor = new Color(d, 0, 127, 0);
-               colors.debugColor = new Color(d, 0, 0, 127);
-               colors.errorColor = new Color(d, 255, 0, 0);
-               colors.warningColor = new Color(d, 255, 127, 0);
-               colors.verboseColor = new Color(d, 0, 0, 0);
-
-               addAction = new Action("add Tab") {
-                       @Override
-                       public void run() {
-                               logPanel.addTab();
-                       }
-               };
-               addAction.setToolTipText("Add LogTab");
-               addAction.setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/Add tab.png"));
-
-               removeAction = new Action("Remove Tab") {
-                       @Override
-                       public void run() {
-                               logPanel.removeTab();
-                       }
-               };
-               removeAction.setToolTipText("Remove LogTab");
-               removeAction.setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/Remove tab.png"));
-
-               editAction = new Action("Edit Tab") {
-                       @Override
-                       public void run() {
-                               logPanel.editTab();
-                       }
-               };
-               editAction.setToolTipText("Edit LogTab");
-               editAction.setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/Edit tab.png"));
-
-               exportAction = new Action("Export Log") {
-                       @Override
-                       public void run() {
-                               logPanel.save();
-                       }
-               };
-               exportAction.setToolTipText("Export Log");
-               exportAction.setImageDescriptor(
-                               ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/Export Log.png")); //$NON-NLS-1$
-
-               clearAction = new Action("Clear Log") {
-                       @Override
-                       public void run() {
-                               logPanel.clear();
-                       }
-               };
-               clearAction.setToolTipText("Clear Log");
-               clearAction.setImageDescriptor(
-                               ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/Clear Log.png")); //$NON-NLS-1$
-
-               LogLevel[] levels = LogLevel.values();
-               logLevelActions = new Action[logLevelIcons.length];
-               for (int i = 0; i < logLevelActions.length; i++) {
-                       String name = levels[i].getStringValue();
-                       logLevelActions[i] = new Action(name, IAction.AS_CHECK_BOX) {
-                               @Override
-                               public void run() {
-                                       // disable the other actions and record
-                                       // current index
-                                       for (int i = 0; i < logLevelActions.length; i++) {
-                                               Action a = logLevelActions[i];
-                                               if (a == this) {
-                                                       if (logPanel.getCurrentLogTab() != null) {
-                                                               if (a.isChecked())
-                                                                       a.setChecked(a.isChecked());
-                                                        logPanel.getCurrentLogTab().setLevel(i , a.isChecked());
-                                                        logPanel.getCurrentLogTab().refill();
-                                                       }
-                                               }
-                                       }
-                               }
-                       };
-                       logLevelActions[i].setChecked(true);
-                       logLevelActions[i].setToolTipText(name);
-                       logLevelActions[i].setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin(logLevelIcons[i]));
-               }
-
-               // now create the log view
-               logPanel = new LogPanel(colors);
-
-               logPanel.setActions(logLevelActions, addAction, removeAction, editAction, exportAction, clearAction);
-               placeActions();
-               logPanel.setActionEnabled(LogPanel.ACTION_NOTHING);
-               logPanel.createPanel(parent);
-
-               // setup the copy action
-               clipboard = new Clipboard(d);
-               IActionBars actionBars = getViewSite().getActionBars();
-               actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), new Action("Copy") {
-                       @Override
-                       public void run() {
-                               logPanel.copy(clipboard);
-                       }
-               });
-
-               // setup the select all action
-               actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), new Action(
-                               "Select All") {
-                       @Override
-                       public void run() {
-                               logPanel.selectAll();
-                       }
-               });
-       }
-
-       @Override
-       public void dispose() {
-               logPanel.stopAll();
-       }
-
-       @Override
-       public void setFocus() {
-               logPanel.setFocus();
-       }
-
-       /**
-        * Place the actions in the ui.
-        */
-       private void placeActions() {
-               IActionBars actionBars = getViewSite().getActionBars();
-
-               // first in the menu
-               IMenuManager menuManager = actionBars.getMenuManager();
-               menuManager.add(addAction);
-               menuManager.add(removeAction);
-               menuManager.add(editAction);
-               menuManager.add(new Separator());
-               menuManager.add(exportAction);
-               menuManager.add(clearAction);
-               menuManager.add(new Separator());
-
-               // and then in the toolbar
-               IToolBarManager toolBarManager = actionBars.getToolBarManager();
-               toolBarManager.add(new Separator());
-               for (Action a : logLevelActions) {
-                       toolBarManager.add(a);
-               }
-               toolBarManager.add(new Separator());
-               toolBarManager.add(addAction);
-               toolBarManager.add(removeAction);
-               toolBarManager.add(editAction);
-               toolBarManager.add(new Separator());
-               toolBarManager.add(exportAction);
-               toolBarManager.add(clearAction);
-               toolBarManager.add(new Separator());
-       }
-
-       public LogPanel getPanel() {
-               return logPanel;
-       }
+public final class LogView extends ViewPart
+{
+
+    public static final String ID = "org.tizen.common.connection.ui.LogView"; //$NON-NLS-1$
+
+    private LogPanel logPanel;
+    private Composite parent; 
+
+    private Action addAction;
+    private Action removeAction;
+    private Action editAction;
+    private Action scrollLockAction;
+    private Action exportAction;
+    private Action clearAction;
+
+    private Action[] viewActions;
+    private Action[] logLevelActions;
+    private final String[] logLevelIcons = { "icons/log/v.png", //$NON-NLS-1S
+            "icons/log/d.png", //$NON-NLS-1S
+            "icons/log/i.png", //$NON-NLS-1S
+            "icons/log/w.png", //$NON-NLS-1S
+            "icons/log/e.png", //$NON-NLS-1S
+    };
+
+    private Clipboard clipboard;
+    private LogColors colors;
+
+    @Override
+    public void createPartControl(Composite p)
+    {
+        parent = p;
+        PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, TizenHelpContextIds.HELP_COMMON_LOG_CONTEXT);
+        Display d = parent.getDisplay();
+        colors = new LogColors(d);
+
+        addAction = new Action("add Tab")
+        {
+            @Override
+            public void run()
+            {
+                logPanel.addTab();
+            }
+        };
+        addAction.setToolTipText("Add LogTab");
+        addAction.setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/add_tab.png"));
+
+        removeAction = new Action("Remove Tab")
+        {
+            @Override
+            public void run()
+            {
+                logPanel.removeTab();
+            }
+        };
+        removeAction.setToolTipText("Remove LogTab");
+        removeAction.setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/remove_tab.png"));
+
+        editAction = new Action("Edit Tab")
+        {
+            @Override
+            public void run()
+            {
+                logPanel.editTab();
+            }
+        };
+        editAction.setToolTipText("Edit LogTab");
+        editAction.setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/edit_tab.png"));
+
+        scrollLockAction = new Action("Scroll Lock")
+        {
+            @Override
+            public void run()
+            {
+                scrollLockAction.setChecked(scrollLockAction.isChecked());
+                logPanel.setScrollLock(scrollLockAction.isChecked());
+            }
+        };
+        scrollLockAction.setToolTipText("Scroll Lock");
+        scrollLockAction.setChecked(false);
+        scrollLockAction.setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/scroll_lock.png"));
+
+        exportAction = new Action("Export the log")
+        {
+            @Override
+            public void run()
+            {
+                logPanel.save();
+            }
+        };
+        exportAction.setToolTipText("Export the log");
+        exportAction.setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/export_log.png")); //$NON-NLS-1$
+
+        clearAction = new Action("Clear the log")
+        {
+            @Override
+            public void run()
+            {
+                logPanel.clear();
+            }
+        };
+        clearAction.setToolTipText("Clear the log");
+        clearAction.setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin("icons/log/clear_log.png")); //$NON-NLS-1$
+
+        LogLevel[] levels = LogLevel.values();
+        logLevelActions = new Action[logLevelIcons.length];
+        for (int i = 0; i < logLevelActions.length; i++)
+        {
+            String name = levels[i].getStringValue();
+            logLevelActions[i] = new Action(name, IAction.AS_CHECK_BOX)
+            {
+                @Override
+                public void run()
+                {
+                    // disable the other actions and record
+                    // current index
+                    for (int i = 0; i < logLevelActions.length; i++)
+                    {
+                        Action a = logLevelActions[i];
+                        if (a == this)
+                        {
+                            if (logPanel.getSelectionLogTab() != null)
+                            {
+                                if (a.isChecked())
+                                    a.setChecked(a.isChecked());
+                                logPanel.setLevel(i, a.isChecked());
+                            }
+                        }
+                    }
+                }
+            };
+            logLevelActions[i].setChecked(true);
+            logLevelActions[i].setToolTipText(name);
+            logLevelActions[i].setImageDescriptor(ConnectionPlugin.getImageDescriptorFromPlugin(logLevelIcons[i]));
+        }
+
+        // now create the log view
+        logPanel = new LogPanel(colors);
+        viewActions = new Action[]{addAction, removeAction, editAction, scrollLockAction, exportAction, clearAction};
+        logPanel.setActions(logLevelActions, viewActions);
+        placeActions();
+        logPanel.setEnabledForActions(LogPanel.NO_TAB);
+        logPanel.createPanel(parent);
+
+        // setup the copy action
+        clipboard = new Clipboard(d);
+        IActionBars actionBars = getViewSite().getActionBars();
+        actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), new Action("Copy")
+        {
+            @Override
+            public void run()
+            {
+                logPanel.copy(clipboard);
+            }
+        });
+
+        // setup the select all action
+        actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), new Action("Select All")
+        {
+            @Override
+            public void run()
+            {
+                logPanel.selectAll();
+            }
+        });
+    }
+
+    @Override
+    public void dispose()
+    {
+        if (clipboard != null && !clipboard.isDisposed())
+        {
+            clipboard.dispose();
+        }
+        logPanel.stopAllTabItems();
+        colors.dispose();
+        super.dispose();
+    }
+
+    @Override
+    public void setFocus()
+    {
+        if(parent != null)
+        {
+            parent.setFocus();
+        }
+        logPanel.setFocus();
+    }
+
+    /**
+     * Place the actions in the ui.
+     */
+    private void placeActions()
+    {
+        IActionBars actionBars = getViewSite().getActionBars();
+
+        // first in the menu
+        IMenuManager menuManager = actionBars.getMenuManager();
+        menuManager.add(addAction);
+        menuManager.add(removeAction);
+        menuManager.add(editAction);
+        menuManager.add(new Separator());
+        menuManager.add(exportAction);
+        menuManager.add(clearAction);
+        menuManager.add(new Separator());
+
+        // and then in the toolbar
+        IToolBarManager toolBarManager = actionBars.getToolBarManager();
+        toolBarManager.add(new Separator());
+        for (Action a : logLevelActions)
+        {
+            toolBarManager.add(a);
+        }
+        toolBarManager.add(new Separator());
+        toolBarManager.add(addAction);
+        toolBarManager.add(removeAction);
+        toolBarManager.add(editAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(scrollLockAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(exportAction);
+        toolBarManager.add(clearAction);
+        toolBarManager.add(new Separator());
+    }
+
+    public LogPanel getPanel()
+    {
+        return logPanel;
+    }
 }
\ No newline at end of file
index d5ec924..2acb7d2 100644 (file)
@@ -3,10 +3,10 @@
 *
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
 *
-* Contact: 
+* Contact:
 * Hoon Kang <h245.kang@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
 */
 package org.tizen.common.connection.ui;
 
+import java.io.IOException;
+
 import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
@@ -39,23 +44,26 @@ import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.ScrollBar;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeColumn;
 import org.eclipse.swt.widgets.TreeItem;
-
+import org.tizen.common.TizenPlatformConstants;
+import org.tizen.common.util.log.Logger;
 import org.tizen.sdblib.FileListingService.FileEntry;
 import org.tizen.sdblib.IDevice;
+import org.tizen.sdblib.MultiLineReceiver;
 
 public class TizenRemoteFileDialog {
 
-       public enum TizenRemoteFileDialogResult {
-               OK,
-               CANCEL
-       }
-       
-       private TizenRemoteFileDialogResult result = TizenRemoteFileDialogResult.CANCEL;
-       private IDevice device;
+    public enum TizenRemoteFileDialogResult {
+        OK,
+        CANCEL
+    }
+
+    private TizenRemoteFileDialogResult result = TizenRemoteFileDialogResult.CANCEL;
+    private IDevice device;
     private Shell shell;
     private Display display;
     private boolean isDirOnly = false;
@@ -64,13 +72,11 @@ public class TizenRemoteFileDialog {
     private FileEntry selectedDir;
     private Tree pathTree;
     private TreeViewer pathTreeViewer;
+    private Composite upper;
 
     TizenRemoteFileContentProvider remoteContentProvider = null;
 
-    public TizenRemoteFileDialog(Shell parent, String dlgTitle, IDevice device,
-                               boolean isDirOnly, String defaultPath)
-                                   throws IllegalArgumentException {
-
+    public TizenRemoteFileDialog(Shell parent, String dlgTitle, IDevice device, boolean isDirOnly, String defaultPath) throws IllegalArgumentException {
         if (parent == null || device == null)
             throw new IllegalArgumentException();
 
@@ -78,14 +84,22 @@ public class TizenRemoteFileDialog {
         shell = createNewShell(parent);
         shell.setText(dlgTitle);
         shell.setSize(300, 400);
+        shell.addListener(SWT.Traverse, new Listener() {
+            public void handleEvent(Event event) {
+                switch (event.detail) {
+                    case SWT.TRAVERSE_ESCAPE:
+                        shell.close();
+                        event.detail = SWT.TRAVERSE_NONE;
+                        event.doit = false;
+                        break;
+                }
+            }
+        });
 
         this.device = device;
         this.isDirOnly = isDirOnly;
 
-        if (defaultPath != null)
-            this.defaultPath = defaultPath;
-        else
-            this.defaultPath = "/";
+        setDefaultPath(defaultPath);
 
         createControls(shell);
     }
@@ -101,7 +115,7 @@ public class TizenRemoteFileDialog {
     }
 
     private void createControls(Composite parent) {
-        Composite upper = new Composite(parent, SWT.NONE);
+        upper = new Composite(parent, SWT.NONE);
         setUpperLayout(upper);
         createPathLabels(upper);
         createPathTree(upper);
@@ -112,18 +126,22 @@ public class TizenRemoteFileDialog {
     }
 
     private void fillPathTree() {
-       createTreeColumn();
-       createTreeViewer();
-        
+        createTreeColumn();
+        createTreeViewer();
+
         FileEntry root = device.getFileListingService().getRoot();
         String[] defaultExpandedPath = defaultPath.substring(1).split("/");
         cacheChild(root, defaultExpandedPath);
-        
+
         pathTreeViewer.setInput(root);
         pathTreeViewer.expandAll();
-        
+
         selectDefaultPath(defaultExpandedPath);
 
+        // set default path to the top item.
+        if (pathTree.getSelection().length > 0)
+            pathTreeViewer.getTree().setTopItem(pathTree.getSelection()[0]);
+
         remoteContentProvider.setInitialize(true);
         pathTreeViewer.refresh();
 
@@ -133,7 +151,7 @@ public class TizenRemoteFileDialog {
                 TreeItem[] items = pathTree.getSelection();
                 if (items.length == 1) {
                     Object object = items[0].getData();
-                    if (object instanceof FileEntry) { 
+                    if (object instanceof FileEntry) {
                         selectedDir = (FileEntry) object;
                         path.setText(selectedDir.getFullPath());
                     }
@@ -159,7 +177,7 @@ public class TizenRemoteFileDialog {
                        }
                }
         }
-        
+
         if (found != null) {
                pathTree.select(found);
                Object data = found.getData();
@@ -179,9 +197,40 @@ public class TizenRemoteFileDialog {
        }
 
        private void createTreeColumn() {
-        TreeColumn nameColumn = new TreeColumn(pathTree, SWT.LEFT);
+           final TreeColumn nameColumn = new TreeColumn(pathTree, SWT.LEFT);
         nameColumn.setText("Name");
         nameColumn.setWidth(100);
+
+        upper.addControlListener(new ControlAdapter() {
+            public void controlResized(ControlEvent e) {
+                Rectangle area = upper.getClientArea();
+                Point size = pathTree.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+                ScrollBar vBar = pathTree.getVerticalBar();
+                int width = area.width - pathTree.computeTrim(0,0,0,0).width - vBar.getSize().x;
+                if (size.y > area.height + pathTree.getHeaderHeight()) {
+                    // Subtract the scrollbar width from the total column width
+                    // if a vertical scrollbar will be required
+                    Point vBarSize = vBar.getSize();
+                    width -= vBarSize.x;
+                }
+                Point oldSize = pathTree.getSize();
+                if (oldSize.x > area.width) {
+                    // table is getting smaller so make the columns 
+                    // smaller first and then resize the table to
+                    // match the client area width
+                    //nameColumn.setWidth(width);
+                    nameColumn.pack();
+                    pathTree.setSize(area.width, area.height);
+                } else {
+                    // table is getting bigger so make the table 
+                    // bigger first and then make the columns wider
+                    // to match the client area width
+                    pathTree.setSize(area.width, area.height);
+                    //nameColumn.setWidth(width);
+                    nameColumn.pack();
+                }
+            }
+        });
        }
 
        private void cacheChild(FileEntry root, String[] defaultExpandedPath) {
@@ -247,7 +296,8 @@ public class TizenRemoteFileDialog {
     }
 
     private void createPathTree(Composite pParent) {
-        pathTree = new Tree(pParent, SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL);
+        // if add SWT.VIRTUAL, horizontal scrol is not shown in case of Linux
+        pathTree = new Tree(pParent, SWT.MULTI | SWT.FULL_SELECTION);
         setTreeLayout(pathTree);
     }
 
@@ -272,7 +322,7 @@ public class TizenRemoteFileDialog {
                         }
                         break;
                     default:
-                               
+
                 }
             }
         });
@@ -309,21 +359,30 @@ public class TizenRemoteFileDialog {
     }
 
     private void runEventLoop(Shell loopShell) {
-        Display tmpDisplay = null;
-
-        if (shell == null)
-               tmpDisplay = Display.getCurrent();
-        else
-               tmpDisplay = loopShell.getDisplay();
-        
-        while (loopShell != null && !loopShell.isDisposed()) {
-            try {
-                if (!tmpDisplay.readAndDispatch())
-                       tmpDisplay.sleep();
-            } catch (SWTException e) {
-                e.printStackTrace();
-            }
+        Display tmpDisplay = loopShell.getDisplay();
+
+        while (!loopShell.isDisposed()) {
+            if (!tmpDisplay.readAndDispatch())
+                tmpDisplay.sleep();
         }
         display.update();
     }
+
+    private void setDefaultPath(final String corePath) {
+        if (corePath == null)
+            defaultPath = "/";
+
+        String command = "ls " + TizenPlatformConstants.PRIVATE_PLATFORM_CORE_PATH + "/*/files/core.* 2&>/dev/null | wc -l";
+
+        try {
+            this.device.executeShellCommand(command, new MultiLineReceiver() {
+                @Override
+                public void processNewLines(String[] lines) {
+                    defaultPath = "0".equals(lines[0]) ? corePath : TizenPlatformConstants.PRIVATE_PLATFORM_CORE_PATH;
+                }
+            });
+        } catch (IOException e) {
+            Logger.error("Problem occurred while executing command '" + command + "'", e.getMessage(), e);
+        }
+    }
 }
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 25931bd..160a675
@@ -107,9 +107,12 @@ public class TizenRemoteFileLabelProvider implements ITableLabelProvider {
                                                case 4:                         
                                                        return entry.getInfo();
                                                default:
+                                                   break;
                                        }
                                }
+                               break;
                        default:
+                           break;
                        }
                } else if (element instanceof IDevice) {
                        IDevice device = (IDevice) element;
diff --git a/org.tizen.common.externals/.classpath b/org.tizen.common.externals/.classpath
new file mode 100644 (file)
index 0000000..8a8f166
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/org.tizen.common.externals/.project b/org.tizen.common.externals/.project
new file mode 100644 (file)
index 0000000..6ae5db5
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.tizen.common.externals</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/org.tizen.common.externals/.settings/org.eclipse.jdt.core.prefs b/org.tizen.common.externals/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..f8bca86
--- /dev/null
@@ -0,0 +1,8 @@
+#Tue Jul 31 14:48:57 KST 2012\r
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6\r
+org.eclipse.jdt.core.compiler.compliance=1.6\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.6\r
diff --git a/org.tizen.common.externals/META-INF/MANIFEST.MF b/org.tizen.common.externals/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..263cd65
--- /dev/null
@@ -0,0 +1,42 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.tizen.common.externals
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.tizen.common.externals.ExternalsPlugin
+Bundle-Vendor: %Bundle-Vendor
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Export-Package: org.mihalis.opal,
+ org.mihalis.opal.angles,
+ org.mihalis.opal.brushedMetalComposite,
+ org.mihalis.opal.checkBoxGroup,
+ org.mihalis.opal.columns,
+ org.mihalis.opal.flatButton,
+ org.mihalis.opal.gradientComposite,
+ org.mihalis.opal.header,
+ org.mihalis.opal.heapManager,
+ org.mihalis.opal.horizontalSpinner,
+ org.mihalis.opal.imageSelector,
+ org.mihalis.opal.infinitePanel,
+ org.mihalis.opal.itemSelector,
+ org.mihalis.opal.launcher,
+ org.mihalis.opal.login,
+ org.mihalis.opal.multiChoice,
+ org.mihalis.opal.notify,
+ org.mihalis.opal.opalDialog,
+ org.mihalis.opal.panels,
+ org.mihalis.opal.preferenceWindow,
+ org.mihalis.opal.preferenceWindow.enabler,
+ org.mihalis.opal.preferenceWindow.widgets,
+ org.mihalis.opal.promptSupport,
+ org.mihalis.opal.rangeSlider,
+ org.mihalis.opal.switchButton,
+ org.mihalis.opal.textAssist,
+ org.mihalis.opal.tipOfTheDay,
+ org.mihalis.opal.titledSeparator,
+ org.mihalis.opal.transitionComposite,
+ org.mihalis.opal.utils,
+ org.tizen.common.externals  
diff --git a/org.tizen.common.externals/OSGI-INF/l10n/bundle.properties b/org.tizen.common.externals/OSGI-INF/l10n/bundle.properties
new file mode 100644 (file)
index 0000000..2debd41
--- /dev/null
@@ -0,0 +1,3 @@
+#Properties file for org.tizen.web.project.wizard
+Bundle-Vendor = Samsung Electronics
+Bundle-Name = Tizen Common externals
\ No newline at end of file
diff --git a/org.tizen.common.externals/about.html b/org.tizen.common.externals/about.html
new file mode 100644 (file)
index 0000000..a72b377
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>May, 2011</p>
+<h3>Tizen SDK</h3>
+
+<p><a href="http://www.tizen.org/" target="_blank">Tizen SDK</a> 
+is a set of Eclipse plug-ins that helps programmers to develop applications for 
+the mobile platform.</p>
+
+<h3>License</h3>
+
+<p>See <a href="about_files/LICENSE-2.0.htm">Apache License, Version 2.0</a>.</p>
+
+<h3>Third Party Content</h3>
+
+<p>The Content includes items that have been sourced from third parties as set out below. If you did not
+receive this Content directly from the Eclipse Foundation, the following is provided for informational
+purposes only, and you should look to the Redistributors license for terms and conditions of use.</p>
+
+<h4>OPAL</h4>
+<p>
+The goal of this project is to propose new widgets for the SWT API. Some widgets are new, some others are a port of existing widgets made with Swing.
+</p>
+
+<p>
+A copy of the license is included in <a href="about_files/epl-v10.html">about_files/epl-v10.html</a>. The home page is located at:
+<ul>
+<a href="http://code.google.com/a/eclipselabs.org/p/opal/">http://code.google.com/a/eclipselabs.org/p/opal/</a>
+</ul>
+</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/org.tizen.common.externals/about_files/LICENSE-2.0.htm b/org.tizen.common.externals/about_files/LICENSE-2.0.htm
new file mode 100644 (file)
index 0000000..f7ca656
--- /dev/null
@@ -0,0 +1,191 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+  <head>
+    <title>Apache License, Version 2.0</title>
+
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+    <meta property="og:image" content="http://www.apache.org/images/asf_logo.gif" />
+
+    <link rel="stylesheet" type="text/css" media="screen" href="/css/style.css">
+    <link rel="stylesheet" type="text/css" media="screen" href="/css/code.css">
+
+    <script type="text/javascript" src="/js/jquery.js"></script>
+    <script type="text/javascript" src="/js/apache_boot.js"></script>
+
+    
+
+    
+    <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file to you under the Apache License, Version 2.0 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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. -->
+  </head>
+
+  <body>
+    <div id="page" class="container_16">
+      <div id="header" class="grid_8">
+        <h1>The Apache Software Foundation</h1>
+        <h2>Apache License, Version 2.0</h2>
+      </div>
+
+      <div class="clear"></div>
+      <div id="content" class="grid_16"><div class="section-content"><p>Apache License<br></br>Version 2.0, January 2004<br></br>
+<a href="http://www.apache.org/licenses/">http://www.apache.org/licenses/</a> </p>
+<p>TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION</p>
+<p><strong><a name="definitions">1. Definitions</a></strong>.</p>
+<p>"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.</p>
+<p>"Licensor" shall mean the copyright owner or entity authorized by the
+copyright owner that is granting the License.</p>
+<p>"Legal Entity" shall mean the union of the acting entity and all other
+entities that control, are controlled by, or are under common control with
+that entity. For the purposes of this definition, "control" means (i) the
+power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty
+percent (50%) or more of the outstanding shares, or (iii) beneficial
+ownership of such entity.</p>
+<p>"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.</p>
+<p>"Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation source,
+and configuration files.</p>
+<p>"Object" form shall mean any form resulting from mechanical transformation
+or translation of a Source form, including but not limited to compiled
+object code, generated documentation, and conversions to other media types.</p>
+<p>"Work" shall mean the work of authorship, whether in Source or Object form,
+made available under the License, as indicated by a copyright notice that
+is included in or attached to the work (an example is provided in the
+Appendix below).</p>
+<p>"Derivative Works" shall mean any work, whether in Source or Object form,
+that is based on (or derived from) the Work and for which the editorial
+revisions, annotations, elaborations, or other modifications represent, as
+a whole, an original work of authorship. For the purposes of this License,
+Derivative Works shall not include works that remain separable from, or
+merely link (or bind by name) to the interfaces of, the Work and Derivative
+Works thereof.</p>
+<p>"Contribution" shall mean any work of authorship, including the original
+version of the Work and any modifications or additions to that Work or
+Derivative Works thereof, that is intentionally submitted to Licensor for
+inclusion in the Work by the copyright owner or by an individual or Legal
+Entity authorized to submit on behalf of the copyright owner. For the
+purposes of this definition, "submitted" means any form of electronic,
+verbal, or written communication sent to the Licensor or its
+representatives, including but not limited to communication on electronic
+mailing lists, source code control systems, and issue tracking systems that
+are managed by, or on behalf of, the Licensor for the purpose of discussing
+and improving the Work, but excluding communication that is conspicuously
+marked or otherwise designated in writing by the copyright owner as "Not a
+Contribution."</p>
+<p>"Contributor" shall mean Licensor and any individual or Legal Entity on
+behalf of whom a Contribution has been received by Licensor and
+subsequently incorporated within the Work.</p>
+<p><strong><a name="copyright">2. Grant of Copyright License</a></strong>. Subject to the
+terms and conditions of this License, each Contributor hereby grants to You
+a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+copyright license to reproduce, prepare Derivative Works of, publicly
+display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.</p>
+<p><strong><a name="patent">3. Grant of Patent License</a></strong>. Subject to the terms
+and conditions of this License, each Contributor hereby grants to You a
+perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+(except as stated in this section) patent license to make, have made, use,
+offer to sell, sell, import, and otherwise transfer the Work, where such
+license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by
+combination of their Contribution(s) with the Work to which such
+Contribution(s) was submitted. If You institute patent litigation against
+any entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that the Work or a Contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of the
+date such litigation is filed.</p>
+<p><strong><a name="redistribution">4. Redistribution</a></strong>. You may reproduce and
+distribute copies of the Work or Derivative Works thereof in any medium,
+with or without modifications, and in Source or Object form, provided that
+You meet the following conditions:</p>
+<ol>
+<li>
+<p>You must give any other recipients of the Work or Derivative Works a
+copy of this License; and</p>
+</li>
+<li>
+<p>You must cause any modified files to carry prominent notices stating
+that You changed the files; and</p>
+</li>
+<li>
+<p>You must retain, in the Source form of any Derivative Works that You
+distribute, all copyright, patent, trademark, and attribution notices from
+the Source form of the Work, excluding those notices that do not pertain to
+any part of the Derivative Works; and</p>
+</li>
+<li>
+<p>If the Work includes a "NOTICE" text file as part of its distribution,
+then any Derivative Works that You distribute must include a readable copy
+of the attribution notices contained within such NOTICE file, excluding
+those notices that do not pertain to any part of the Derivative Works, in
+at least one of the following places: within a NOTICE text file distributed
+as part of the Derivative Works; within the Source form or documentation,
+if provided along with the Derivative Works; or, within a display generated
+by the Derivative Works, if and wherever such third-party notices normally
+appear. The contents of the NOTICE file are for informational purposes only
+and do not modify the License. You may add Your own attribution notices
+within Derivative Works that You distribute, alongside or as an addendum to
+the NOTICE text from the Work, provided that such additional attribution
+notices cannot be construed as modifying the License.
+You may add Your own copyright statement to Your modifications and may
+provide additional or different license terms and conditions for use,
+reproduction, or distribution of Your modifications, or for any such
+Derivative Works as a whole, provided Your use, reproduction, and
+distribution of the Work otherwise complies with the conditions stated in
+this License.</p>
+</li>
+</ol>
+<p><strong><a name="contributions">5. Submission of Contributions</a></strong>. Unless You
+explicitly state otherwise, any Contribution intentionally submitted for
+inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the
+terms of any separate license agreement you may have executed with Licensor
+regarding such Contributions.</p>
+<p><strong><a name="trademarks">6. Trademarks</a></strong>. This License does not grant
+permission to use the trade names, trademarks, service marks, or product
+names of the Licensor, except as required for reasonable and customary use
+in describing the origin of the Work and reproducing the content of the
+NOTICE file.</p>
+<p><strong><a name="no-warranty">7. Disclaimer of Warranty</a></strong>. Unless required by
+applicable law or agreed to in writing, Licensor provides the Work (and
+each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including,
+without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You
+are solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise
+of permissions under this License.</p>
+<p><strong><a name="no-liability">8. Limitation of Liability</a></strong>. In no event and
+under no legal theory, whether in tort (including negligence), contract, or
+otherwise, unless required by applicable law (such as deliberate and
+grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special,
+incidental, or consequential damages of any character arising as a result
+of this License or out of the use or inability to use the Work (including
+but not limited to damages for loss of goodwill, work stoppage, computer
+failure or malfunction, or any and all other commercial damages or losses),
+even if such Contributor has been advised of the possibility of such
+damages.</p>
+<p><strong><a name="additional">9. Accepting Warranty or Additional Liability</a></strong>.
+While redistributing the Work or Derivative Works thereof, You may choose
+to offer, and charge a fee for, acceptance of support, warranty, indemnity,
+or other liability obligations and/or rights consistent with this License.
+However, in accepting such obligations, You may act only on Your own behalf
+and on Your sole responsibility, not on behalf of any other Contributor,
+and only if You agree to indemnify, defend, and hold each Contributor
+harmless for any liability incurred by, or claims asserted against, such
+Contributor by reason of your accepting any such warranty or additional
+liability.</p>
+<p>END OF TERMS AND CONDITIONS</p>
+
+    <div class="clear"></div>
+    
+    </div>
+    <div id="copyright" class="container_16">
+      <p>Copyright &#169; 2011 The Apache Software Foundation, Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.<br/>Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
+    </div>
+  </body>
+</html>
diff --git a/org.tizen.common.externals/about_files/epl-v10.html b/org.tizen.common.externals/about_files/epl-v10.html
new file mode 100644 (file)
index 0000000..fd39122
--- /dev/null
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Public License - Version 1.0</title>
+<style type="text/css">
+  body {
+    size: 8.5in 11.0in;
+    margin: 0.25in 0.5in 0.25in 0.5in;
+    tab-interval: 0.5in;
+    }
+  p {          
+    margin-left: auto;
+    margin-top:  0.5em;
+    margin-bottom: 0.5em;
+    }
+  p.list {
+       margin-left: 0.5in;
+    margin-top:  0.05em;
+    margin-bottom: 0.05em;
+    }
+  </style>
+
+</head>
+
+<body lang="EN-US">
+
+<h2>Eclipse Public License - v 1.0</h2>
+
+<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
+AGREEMENT.</p>
+
+<p><b>1. DEFINITIONS</b></p>
+
+<p>&quot;Contribution&quot; means:</p>
+
+<p class="list">a) in the case of the initial Contributor, the initial
+code and documentation distributed under this Agreement, and</p>
+<p class="list">b) in the case of each subsequent Contributor:</p>
+<p class="list">i) changes to the Program, and</p>
+<p class="list">ii) additions to the Program;</p>
+<p class="list">where such changes and/or additions to the Program
+originate from and are distributed by that particular Contributor. A
+Contribution 'originates' from a Contributor if it was added to the
+Program by such Contributor itself or anyone acting on such
+Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii)
+are not derivative works of the Program.</p>
+
+<p>&quot;Contributor&quot; means any person or entity that distributes
+the Program.</p>
+
+<p>&quot;Licensed Patents&quot; mean patent claims licensable by a
+Contributor which are necessarily infringed by the use or sale of its
+Contribution alone or when combined with the Program.</p>
+
+<p>&quot;Program&quot; means the Contributions distributed in accordance
+with this Agreement.</p>
+
+<p>&quot;Recipient&quot; means anyone who receives the Program under
+this Agreement, including all Contributors.</p>
+
+<p><b>2. GRANT OF RIGHTS</b></p>
+
+<p class="list">a) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free copyright license to reproduce, prepare derivative works
+of, publicly display, publicly perform, distribute and sublicense the
+Contribution of such Contributor, if any, and such derivative works, in
+source code and object code form.</p>
+
+<p class="list">b) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free patent license under Licensed Patents to make, use, sell,
+offer to sell, import and otherwise transfer the Contribution of such
+Contributor, if any, in source code and object code form. This patent
+license shall apply to the combination of the Contribution and the
+Program if, at the time the Contribution is added by the Contributor,
+such addition of the Contribution causes such combination to be covered
+by the Licensed Patents. The patent license shall not apply to any other
+combinations which include the Contribution. No hardware per se is
+licensed hereunder.</p>
+
+<p class="list">c) Recipient understands that although each Contributor
+grants the licenses to its Contributions set forth herein, no assurances
+are provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility to
+secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow Recipient
+to distribute the Program, it is Recipient's responsibility to acquire
+that license before distributing the Program.</p>
+
+<p class="list">d) Each Contributor represents that to its knowledge it
+has sufficient copyright rights in its Contribution, if any, to grant
+the copyright license set forth in this Agreement.</p>
+
+<p><b>3. REQUIREMENTS</b></p>
+
+<p>A Contributor may choose to distribute the Program in object code
+form under its own license agreement, provided that:</p>
+
+<p class="list">a) it complies with the terms and conditions of this
+Agreement; and</p>
+
+<p class="list">b) its license agreement:</p>
+
+<p class="list">i) effectively disclaims on behalf of all Contributors
+all warranties and conditions, express and implied, including warranties
+or conditions of title and non-infringement, and implied warranties or
+conditions of merchantability and fitness for a particular purpose;</p>
+
+<p class="list">ii) effectively excludes on behalf of all Contributors
+all liability for damages, including direct, indirect, special,
+incidental and consequential damages, such as lost profits;</p>
+
+<p class="list">iii) states that any provisions which differ from this
+Agreement are offered by that Contributor alone and not by any other
+party; and</p>
+
+<p class="list">iv) states that source code for the Program is available
+from such Contributor, and informs licensees how to obtain it in a
+reasonable manner on or through a medium customarily used for software
+exchange.</p>
+
+<p>When the Program is made available in source code form:</p>
+
+<p class="list">a) it must be made available under this Agreement; and</p>
+
+<p class="list">b) a copy of this Agreement must be included with each
+copy of the Program.</p>
+
+<p>Contributors may not remove or alter any copyright notices contained
+within the Program.</p>
+
+<p>Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.</p>
+
+<p><b>4. COMMERCIAL DISTRIBUTION</b></p>
+
+<p>Commercial distributors of software may accept certain
+responsibilities with respect to end users, business partners and the
+like. While this license is intended to facilitate the commercial use of
+the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create
+potential liability for other Contributors. Therefore, if a Contributor
+includes the Program in a commercial product offering, such Contributor
+(&quot;Commercial Contributor&quot;) hereby agrees to defend and
+indemnify every other Contributor (&quot;Indemnified Contributor&quot;)
+against any losses, damages and costs (collectively &quot;Losses&quot;)
+arising from claims, lawsuits and other legal actions brought by a third
+party against the Indemnified Contributor to the extent caused by the
+acts or omissions of such Commercial Contributor in connection with its
+distribution of the Program in a commercial product offering. The
+obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In
+order to qualify, an Indemnified Contributor must: a) promptly notify
+the Commercial Contributor in writing of such claim, and b) allow the
+Commercial Contributor to control, and cooperate with the Commercial
+Contributor in, the defense and any related settlement negotiations. The
+Indemnified Contributor may participate in any such claim at its own
+expense.</p>
+
+<p>For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.</p>
+
+<p><b>5. NO WARRANTY</b></p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS
+OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to
+the risks and costs of program errors, compliance with applicable laws,
+damage to or loss of data, programs or equipment, and unavailability or
+interruption of operations.</p>
+
+<p><b>6. DISCLAIMER OF LIABILITY</b></p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
+NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p>
+
+<p><b>7. GENERAL</b></p>
+
+<p>If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further action
+by the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.</p>
+
+<p>If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other
+software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the
+date such litigation is filed.</p>
+
+<p>All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of time
+after becoming aware of such noncompliance. If all Recipient's rights
+under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive.</p>
+
+<p>Everyone is permitted to copy and distribute copies of this
+Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The
+Agreement Steward reserves the right to publish new versions (including
+revisions) of this Agreement from time to time. No one other than the
+Agreement Steward has the right to modify this Agreement. The Eclipse
+Foundation is the initial Agreement Steward. The Eclipse Foundation may
+assign the responsibility to serve as the Agreement Steward to a
+suitable separate entity. Each new version of the Agreement will be
+given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the
+Agreement under which it was received. In addition, after a new version
+of the Agreement is published, Contributor may elect to distribute the
+Program (including its Contributions) under the new version. Except as
+expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
+rights or licenses to the intellectual property of any Contributor under
+this Agreement, whether expressly, by implication, estoppel or
+otherwise. All rights in the Program not expressly granted under this
+Agreement are reserved.</p>
+
+<p>This Agreement is governed by the laws of the State of New York and
+the intellectual property laws of the United States of America. No party
+to this Agreement will bring a legal action under this Agreement more
+than one year after the cause of action arose. Each party waives its
+rights to a jury trial in any resulting litigation.</p>
+
+</body>
+
+</html>
diff --git a/org.tizen.common.externals/build.properties b/org.tizen.common.externals/build.properties
new file mode 100644 (file)
index 0000000..1477b3f
--- /dev/null
@@ -0,0 +1,8 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               OSGI-INF/,\\r
+               resources/,\\r
+               about.html,\\r
+               about_files/\r
diff --git a/org.tizen.common.externals/resources/opal.properties b/org.tizen.common.externals/resources/opal.properties
new file mode 100644 (file)
index 0000000..ef0a470
--- /dev/null
@@ -0,0 +1,35 @@
+Ok=OK\r
+Cancel=Cancel\r
+Close=Close\r
+Yes=Yes\r
+No=No\r
+MoreDetails=More Details\r
+FewerDetails=Fewer Details\r
+Details=Details\r
+Information=Information\r
+Error=Error\r
+Question=Question\r
+Warning=Warning\r
+Exception=Exception\r
+Choice=Choice\r
+Select=Select\r
+Input=Input\r
+ApplicationError=Application Error\r
+megabytes=Mb\r
+performGC=Perform GC\r
+login=Login\r
+name=Name\r
+password=Password\r
+rememberPassword=Remember password\r
+loginFailed=Login failed\r
+tipOfTheDay=Tip of the day\r
+didYouKnow=Did you know...\r
+showTipAtStartup=Show Tip at startup\r
+previousTip=< Previous Tip\r
+nextTip=Next Tip >\r
+choose=Choose\r
+preferences=Preferences\r
+validURL=Please enter a valid URL\r
+chooseDirectory=Please choose a directory\r
+bold=bold\r
+italic=italic\r
diff --git a/org.tizen.common.externals/resources/opal_de_DE.properties b/org.tizen.common.externals/resources/opal_de_DE.properties
new file mode 100644 (file)
index 0000000..b6e5e55
--- /dev/null
@@ -0,0 +1,35 @@
+OK=OK\r
+Cancel=Abbrechen\r
+Close=Schließen\r
+Yes=Ja\r
+No=Nein\r
+MoreDetails=Weitere Details\r
+FewerDetails=Weniger Details\r
+Details=Details\r
+Information=Information\r
+Error=Fehler\r
+Question=Frage\r
+Warning=Warnung\r
+Exception=Ausnahme\r
+Choice=Auswahl\r
+Select=Auswählen\r
+Input=Eingabe\r
+ApplicationError=Application Error\r
+megabytes=Mb\r
+performGC=Perform GC\r
+login=Login\r
+name=Name\r
+password=Passwort\r
+rememberPassword=Passwort merken\r
+loginFailed=Login failed\r
+tipOfTheDay=Tip of the day\r
+didYouKnow=Did you know...\r
+showTipAtStartup=Show Tip at startup\r
+previousTip=< Previous Tip\r
+nextTip=Next Tip >\r
+choose=Choose\r
+preferences=Preferences\r
+validURL=Please enter a valid URL\r
+chooseDirectory=Please choose a directory\r
+bold=bold\r
+italic=italic
\ No newline at end of file
diff --git a/org.tizen.common.externals/resources/opal_es_ES.properties b/org.tizen.common.externals/resources/opal_es_ES.properties
new file mode 100644 (file)
index 0000000..afb3798
--- /dev/null
@@ -0,0 +1,35 @@
+Ok=OK\r
+Cancel=Cancelar\r
+Close=Cerrar\r
+Yes=Sí\r
+No=No\r
+MoreDetails=Más detalles\r
+FewerDetails=Pocos detalles\r
+Details=Detalles\r
+Information=Información\r
+Error=Error\r
+Question=Pregunta\r
+Warning=Advertencia\r
+Exception=Excepción\r
+Choice=Elección\r
+Select=Seleccione\r
+Input=Entrada\r
+ApplicationError=Error de la aplicación\r
+megabytes=Mb\r
+performGC=Ejecutar GC\r
+login=Conexión\r
+name=Nombre\r
+password=Contraseña\r
+rememberPassword=Recordar contraseña\r
+loginFailed=Fallo en la conexión\r
+tipOfTheDay=Consejo diario\r
+didYouKnow=Sabias que...?\r
+showTipAtStartup=Mostrar consejos al inicio\r
+previousTip=<Consejo anterior\r
+nextTip=Siguiente consejo>\r
+choose=Elegir\r
+preferences=Preferencias\r
+validURL=Por favor, introduzca una URL válida\r
+chooseDirectory=Por favor, escoge un directorio\r
+bold=negrita\r
+italic=cursiva
\ No newline at end of file
diff --git a/org.tizen.common.externals/resources/opal_fr_FR.properties b/org.tizen.common.externals/resources/opal_fr_FR.properties
new file mode 100644 (file)
index 0000000..a7ef841
--- /dev/null
@@ -0,0 +1,35 @@
+OK=OK\r
+Cancel=Annuler\r
+Close=Fermer\r
+Yes=Oui\r
+No=Non\r
+MoreDetails=Plus de détails\r
+FewerDetails=Moins de détails\r
+Details=Détails\r
+Information=Information\r
+Error=Erreur\r
+Question=Question\r
+Warning=Avertissement\r
+Exception=Exception\r
+Choice=Choix\r
+Select=Sélection\r
+Input=Entrée\r
+ApplicationError=Erreur applicative\r
+megabytes=Mo\r
+performGC=Lancer le ramasse-miettes (GC)\r
+login=Identification\r
+name=Nom\r
+password=Mot de passe\r
+rememberPassword=Se souvenir de mon mot de passe\r
+loginFailed=Echec de l'authentification\r
+tipOfTheDay=Astuce du jour\r
+didYouKnow=Le savez-vous ?\r
+showTipAtStartup=Afficher les astuces au démarrage\r
+previousTip=< Astuce précédente\r
+nextTip=Astuce suivante >\r
+choose=Choisir\r
+preferences=Préférences\r
+validURL=Merci de saisir une URL valide s'il vous plait\r
+chooseDirectory=Veuillez choisir un répertoire\r
+bold=gras\r
+italic=italique
\ No newline at end of file
diff --git a/org.tizen.common.externals/resources/opal_it_IT.properties b/org.tizen.common.externals/resources/opal_it_IT.properties
new file mode 100644 (file)
index 0000000..189900b
--- /dev/null
@@ -0,0 +1,35 @@
+OK=OK\r
+Cancel=Annulla\r
+Close=Chiudi\r
+Yes=Si\r
+No=No\r
+MoreDetails=Pi\u00F9 Dettagli\r
+FewerDetails=Meno Dettagli\r
+Details=Dettagli\r
+Information=Informazione\r
+Error=Errore\r
+Question=Domanda\r
+Warning=Avvertenza\r
+Exception=Eccezione\r
+Choice=Scelta\r
+Select=Seleziona\r
+Input=Input\r
+ApplicationError=Errore di applicazione\r
+megabytes=Mb\r
+performGC=Perform GC\r
+login=Accesso\r
+name=Nome\r
+password=Password\r
+rememberPassword=Remember password\r
+loginFailed=Login failed\r
+tipOfTheDay=Tip of the day\r
+didYouKnow=Did you know...\r
+showTipAtStartup=Show Tip at startup\r
+previousTip=< Previous Tip\r
+nextTip=Next Tip >\r
+choose=Choose\r
+preferences=Preferences\r
+validURL=Please enter a valid URL\r
+chooseDirectory=Please choose a directory\r
+bold=bold\r
+italic=italic
\ No newline at end of file
diff --git a/org.tizen.common.externals/resources/opal_pl_PL.properties b/org.tizen.common.externals/resources/opal_pl_PL.properties
new file mode 100644 (file)
index 0000000..2d8e8dd
--- /dev/null
@@ -0,0 +1,35 @@
+Ok=OK\r
+Cancel=Anuluj\r
+Close=Zamknij\r
+Yes=Tak\r
+No=Nie\r
+MoreDetails=WiÄ™cej szczegółów\r
+FewerDetails=Mniej szczegółów\r
+Details=Szczegóły\r
+Information=Informacja\r
+Error=BÅ‚Ä…d\r
+Question=Pytanie\r
+Warning=Ostrzeżenie\r
+Exception=WyjÄ…tek\r
+Choice=Wybór\r
+Select=Wybór\r
+Input=Wprowadzanie\r
+ApplicationError=BÅ‚Ä…d aplikacji\r
+megabytes=Mb\r
+performGC=Perform GC\r
+login=Login\r
+name=Name\r
+password=Password\r
+rememberPassword=Remember password\r
+loginFailed=Login failed\r
+tipOfTheDay=Tip of the day\r
+didYouKnow=Did you know...\r
+showTipAtStartup=Show Tip at startup\r
+previousTip=< Previous Tip\r
+nextTip=Next Tip >\r
+choose=Choose\r
+preferences=Preferences\r
+validURL=Please enter a valid URL\r
+chooseDirectory=Please choose a directory\r
+bold=bold\r
+italic=italic
\ No newline at end of file
diff --git a/org.tizen.common.externals/resources/opal_pt_BR.properties b/org.tizen.common.externals/resources/opal_pt_BR.properties
new file mode 100644 (file)
index 0000000..5029102
--- /dev/null
@@ -0,0 +1,35 @@
+Ok=OK\r
+Cancel=Cancelar\r
+Close=Fechar\r
+Yes=Sim\r
+No=Não\r
+MoreDetails=Mais detalhes\r
+FewerDetails=Menos detalhes\r
+Details=Detalhes\r
+Information=Informação\r
+Error=Erro\r
+Question=Questão\r
+Warning=Aviso\r
+Exception=Exceção\r
+Choice=Escolher\r
+Select=Selecionar\r
+Input=Entrar\r
+ApplicationError=Erro da aplicação\r
+megabytes=Mb\r
+performGC=Perform GC\r
+login=Login\r
+name=Name\r
+password=Password\r
+rememberPassword=Remember password\r
+loginFailed=Login failed\r
+tipOfTheDay=Tip of the day\r
+didYouKnow=Did you know...\r
+showTipAtStartup=Show Tip at startup\r
+previousTip=< Previous Tip\r
+nextTip=Next Tip >\r
+choose=Choose\r
+preferences=Preferences\r
+validURL=Please enter a valid URL\r
+chooseDirectory=Please choose a directory\r
+bold=bold\r
+italic=italic
\ No newline at end of file
diff --git a/org.tizen.common.externals/resources/opal_zh_CN.properties b/org.tizen.common.externals/resources/opal_zh_CN.properties
new file mode 100644 (file)
index 0000000..b479add
--- /dev/null
@@ -0,0 +1,35 @@
+Ok=\u786e\u5b9a\r
+Cancel=\u653e\u5f03\r
+Close=\u5173\u95ed\r
+Yes=\u662f\r
+No=\u5426\r
+MoreDetails=\u8be6\u7ec6\u4fe1\u606f\r
+FewerDetails=\u7b80\u660e\u4fe1\u606f\r
+Details=\u4fe1\u606f\r
+Information=\u4fe1\u606f\r
+Error=\u9519\u8bef\r
+Question=\u95ee\u9898\r
+Warning=\u8b66\u544a\r
+Exception=\u5f02\u5e38\r
+Choice=\u9009\u9879\r
+Select=\u9009\u62e9\r
+Input=\u8f93\u5165\r
+ApplicationError=Application Error\r
+megabytes=Mb\r
+performGC=Perform GC\r
+login=Login\r
+name=Name\r
+password=Password\r
+rememberPassword=Remember password\r
+loginFailed=Login failed\r
+tipOfTheDay=Tip of the day\r
+didYouKnow=Did you know...\r
+showTipAtStartup=Show Tip at startup\r
+previousTip=< Previous Tip\r
+nextTip=Next Tip >\r
+choose=Choose\r
+preferences=Preferences\r
+validURL=Please enter a valid URL\r
+chooseDirectory=Please choose a directory\r
+bold=bold\r
+italic=italic
\ No newline at end of file
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/OpalItem.java b/org.tizen.common.externals/src/org/mihalis/opal/OpalItem.java
new file mode 100644 (file)
index 0000000..a06f1de
--- /dev/null
@@ -0,0 +1,158 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal;\r
+\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.Image;\r
+\r
+/**\r
+ * Instances of this object are items manipulated by the widgets of the Opal Project. These items are highly customizable, you can set :\r
+ * <ul>\r
+ * <li>Background and foreground colors,\r
+ * <li>Font\r
+ * <li>Image\r
+ * <li>Text\r
+ * <li>Height\r
+ * </ul>\r
+ * You can also store data using the <code>setData<code> methods.\r
+ * \r
+ */\r
+public abstract class OpalItem {\r
+\r
+    private Map<String, Object> data;\r
+    private Object datum;\r
+    private Color background;\r
+    private Font font;\r
+    private Color foreground;\r
+    private Image image;\r
+    private String text;\r
+    private int height = -1;\r
+\r
+    /**\r
+     * @return the background color of the item\r
+     */\r
+    public Color getBackground() {\r
+        return this.background;\r
+    }\r
+\r
+    /**\r
+     * @return the the data stored in this item\r
+     */\r
+    public Object getData() {\r
+        return this.datum;\r
+    }\r
+\r
+    /**\r
+     * @param key a key\r
+     * @return the the data stored in this item associated to this key\r
+     */\r
+    public Object getData(final String key) {\r
+        return this.data.get(key);\r
+    }\r
+\r
+    /**\r
+     * @return the font of the item\r
+     */\r
+    public Font getFont() {\r
+        return this.font;\r
+    }\r
+\r
+    /**\r
+     * @return the foreground color of the item\r
+     */\r
+    public Color getForeground() {\r
+        return this.foreground;\r
+    }\r
+\r
+    /**\r
+     * @return the height of the item\r
+     */\r
+    public int getHeight() {\r
+        return this.height;\r
+    }\r
+\r
+    /**\r
+     * @return the image stored in this item\r
+     */\r
+    public Image getImage() {\r
+        return this.image;\r
+    }\r
+\r
+    /**\r
+     * @return the text stored in this item\r
+     */\r
+    public String getText() {\r
+        return this.text;\r
+    }\r
+\r
+    /**\r
+     * @param background set the background color of this item\r
+     */\r
+    public void setBackground(final Color background) {\r
+        this.background = background;\r
+    }\r
+\r
+    /**\r
+     * @param font set the font of this item\r
+     */\r
+    public void setFont(final Font font) {\r
+        this.font = font;\r
+    }\r
+\r
+    /**\r
+     * @param foreground set the foreground color of this item\r
+     */\r
+    public void setForeground(final Color foreground) {\r
+        this.foreground = foreground;\r
+    }\r
+\r
+    /**\r
+     * @param height set the height of this item\r
+     */\r
+    public void setHeight(final int height) {\r
+        this.height = height;\r
+    }\r
+\r
+    /**\r
+     * @param image set the image of this item\r
+     */\r
+    public void setImage(final Image image) {\r
+        this.image = image;\r
+    }\r
+\r
+    /**\r
+     * @param text set the text of this item\r
+     */\r
+    public void setText(final String text) {\r
+        this.text = text;\r
+    }\r
+\r
+    /**\r
+     * @param data set the data stored in this item\r
+     */\r
+    public void setData(final Object data) {\r
+        this.datum = data;\r
+    }\r
+\r
+    /**\r
+     * Store a data associated to a given key in this item\r
+     * \r
+     * @param key key\r
+     * @param value value associated to this key\r
+     */\r
+    public void setData(final String key, final Object value) {\r
+        this.data.put(key, value);\r
+    }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/angles/AngleSlider.java b/org.tizen.common.externals/src/org/mihalis/opal/angles/AngleSlider.java
new file mode 100644 (file)
index 0000000..bf36ba7
--- /dev/null
@@ -0,0 +1,246 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *     inspired by the Swing AngleSlider by Jeremy (http://javagraphics.blogspot.com/2008/05/angles-need-gui-widget-for-angles.html)\r
+ *******************************************************************************/\r
+package org.mihalis.opal.angles;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class provide a selectable user interface object that can\r
+ * be used to pick angles.\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>BORDER</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>Selection</dd>\r
+ * </dl>\r
+ */\r
+public class AngleSlider extends Canvas {\r
+\r
+       private static final int WHOLE_RADIUS = 40;\r
+       private static final int BUTTON_RADIUS = 10;\r
+       private static final int STEP = 5;\r
+\r
+       private final Image backgroundImage;\r
+       private final Image buttonFocus;\r
+       private final Image buttonNoFocus;\r
+       private int selection;\r
+       private final List<SelectionListener> selectionListeners;\r
+       private boolean mousePressed;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent.\r
+        * \r
+        * @param parent a widget which will be the parent of the new instance\r
+        *            (cannot be null)\r
+        * @param style not used\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        */\r
+       public AngleSlider(final Composite parent, final int style) {\r
+               super(parent, style | SWT.DOUBLE_BUFFERED);\r
+\r
+               this.backgroundImage = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/angleBackground.png"));\r
+\r
+               this.buttonFocus = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/angleButtonFocus.png"));\r
+               this.buttonNoFocus = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/angleButtonFocusLost.png"));\r
+\r
+               this.addListener(SWT.Paint, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               paintControl(event);\r
+                       }\r
+               });\r
+\r
+               this.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent arg0) {\r
+                               SWTGraphicUtil.dispose(AngleSlider.this.backgroundImage);\r
+                               SWTGraphicUtil.dispose(AngleSlider.this.buttonFocus);\r
+                               SWTGraphicUtil.dispose(AngleSlider.this.buttonNoFocus);\r
+                       }\r
+               });\r
+\r
+               this.addListener(SWT.MouseDown, createMouseListener());\r
+               this.addListener(SWT.MouseUp, createMouseListener());\r
+               this.addListener(SWT.MouseMove, createMouseListener());\r
+               this.addListener(SWT.KeyDown, createKeyListener());\r
+\r
+               this.selection = 0;\r
+               this.selectionListeners = new ArrayList<SelectionListener>();\r
+\r
+       }\r
+\r
+       private void paintControl(final Event event) {\r
+               final GC gc = event.gc;\r
+\r
+               gc.drawImage(this.backgroundImage, 0, 0);\r
+\r
+               float angle = this.selection / 360f;\r
+               angle = (float) (angle * 2 * Math.PI - 0.5 * Math.PI);\r
+\r
+               final float centerX = WHOLE_RADIUS / 2f;\r
+               final float centerY = WHOLE_RADIUS / 2f;\r
+               final float radius = BUTTON_RADIUS;\r
+               final float x = (float) (centerX - radius * Math.cos(angle));\r
+               final float y = (float) (centerY - radius * Math.sin(angle));\r
+\r
+               if (isFocusControl()) {\r
+                       gc.drawImage(this.buttonFocus, (int) x - 2, (int) y - 2);\r
+               } else {\r
+                       gc.drawImage(this.buttonNoFocus, (int) x - 2, (int) y - 2);\r
+               }\r
+\r
+               if (!isEnabled()) {\r
+                       gc.setAlpha(127);\r
+                       gc.setAntialias(SWT.ON);\r
+                       gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+                       gc.fillOval(4, 4, WHOLE_RADIUS - 7, WHOLE_RADIUS - 7);\r
+               }\r
+       }\r
+\r
+       private Listener createMouseListener() {\r
+               return new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               if (!isEnabled()) {\r
+                                       return;\r
+                               }\r
+\r
+                               if (event.type == SWT.MouseDown) {\r
+                                       AngleSlider.this.mousePressed = true;\r
+                               }\r
+                               if (event.type == SWT.MouseDown || event.type == SWT.MouseMove && AngleSlider.this.mousePressed) {\r
+                                       final float deltaX = event.x - WHOLE_RADIUS / 2f;\r
+                                       final float deltaY = event.y - WHOLE_RADIUS / 2f;\r
+                                       final double angle = Math.atan2(deltaX, deltaY);\r
+                                       AngleSlider.this.selection = 360 - (int) (360 * angle / (2 * Math.PI) + 360) % 360;\r
+\r
+                                       AngleSlider.this.redraw();\r
+                               }\r
+                               if (event.type == SWT.MouseUp) {\r
+                                       AngleSlider.this.mousePressed = false;\r
+                                       fireSelectionListeners(event);\r
+                               }\r
+                       }\r
+               };\r
+       }\r
+\r
+       private void fireSelectionListeners(final Event event) {\r
+               for (final SelectionListener selectionListener : this.selectionListeners) {\r
+                       selectionListener.widgetSelected(new SelectionEvent(event));\r
+               }\r
+\r
+       }\r
+\r
+       private Listener createKeyListener() {\r
+               return new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               if (!isEnabled()) {\r
+                                       return;\r
+                               }\r
+                               if (event.type != SWT.KeyDown) {\r
+                                       return;\r
+                               }\r
+                               if (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_LEFT) {\r
+                                       setSelection(AngleSlider.this.selection + STEP);\r
+                               }\r
+                               if (event.keyCode == SWT.ARROW_DOWN || event.keyCode == SWT.ARROW_RIGHT) {\r
+                                       setSelection(AngleSlider.this.selection - STEP);\r
+                               }\r
+                       }\r
+               };\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Scale#addSelectionListener(org.eclipse.swt.events.SelectionListener)\r
+        */\r
+       public void addSelectionListener(final SelectionListener selectionListener) {\r
+               checkWidget();\r
+               this.selectionListeners.add(selectionListener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)\r
+        */\r
+       @Override\r
+       public Point computeSize(final int wHint, final int hHint, final boolean changed) {\r
+               checkWidget();\r
+               return new Point(WHOLE_RADIUS, WHOLE_RADIUS);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Scale#getSelection()\r
+        */\r
+       public int getSelection() {\r
+               checkWidget();\r
+               return this.selection;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Scale#removeSelectionListener(org.eclipse.swt.events.SelectionListener)\r
+        */\r
+       public void removeSelectionListener(final SelectionListener selectionListener) {\r
+               checkWidget();\r
+               this.selectionListeners.remove(selectionListener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#setEnabled(boolean)\r
+        */\r
+       @Override\r
+       public void setEnabled(final boolean enabled) {\r
+               super.setEnabled(enabled);\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Scale#setSelection(int)\r
+        */\r
+       public void setSelection(final int selection) {\r
+               checkWidget();\r
+               if (selection < 0 || selection > 360) {\r
+                       SWT.error(SWT.ERROR_CANNOT_SET_SELECTION);\r
+               }\r
+               this.selection = selection;\r
+               fireSelectionListeners(new Event());\r
+               redraw();\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/brushedMetalComposite/BrushedMetalComposite.java b/org.tizen.common.externals/src/org/mihalis/opal/brushedMetalComposite/BrushedMetalComposite.java
new file mode 100644 (file)
index 0000000..893b8c6
--- /dev/null
@@ -0,0 +1,378 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Jerry Huxtable (http://www.jhlabs.com/index.html) - initial API and implementation (on SWING), \r
+ *     Laurent CARON (laurent.caron at gmail dot com) - port to SWT\r
+ *******************************************************************************/\r
+package org.mihalis.opal.brushedMetalComposite;\r
+\r
+import java.util.Random;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.ImageData;\r
+import org.eclipse.swt.graphics.PaletteData;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are controls which background's texture is brushed\r
+ * metal "a la Mac"\r
+ */\r
+public class BrushedMetalComposite extends Composite {\r
+\r
+       private Image oldImage;\r
+       private int radius = 10;\r
+       private float amount = 0.1f;\r
+       private int color = 0xff888888;\r
+       private float shine = 0.1f;\r
+       private boolean monochrome = true;\r
+       private Random randomNumbers;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a widget which will be the parent of the new instance\r
+        *            (cannot be null)\r
+        * @param style the style of widget to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        * @see Composite#Composite(Composite, int)\r
+        * @see SWT#NO_BACKGROUND\r
+        * @see SWT#NO_FOCUS\r
+        * @see SWT#NO_MERGE_PAINTS\r
+        * @see SWT#NO_REDRAW_RESIZE\r
+        * @see SWT#NO_RADIO_GROUP\r
+        * @see SWT#EMBEDDED\r
+        * @see SWT#DOUBLE_BUFFERED\r
+        * @see Widget#getStyle\r
+        */\r
+       public BrushedMetalComposite(final Composite parent, final int style) {\r
+               super(parent, style);\r
+               this.addListener(SWT.Resize, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               BrushedMetalComposite.this.redrawComposite();\r
+                       }\r
+               });\r
+\r
+               parent.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(BrushedMetalComposite.this.oldImage);\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Redraws the composite\r
+        */\r
+       private void redrawComposite() {\r
+               final Display display = this.getDisplay();\r
+               final Rectangle rect = this.getClientArea();\r
+               final ImageData imageData = this.drawBrushedMetalBackground(Math.max(1, rect.width), Math.max(1, rect.width));\r
+               final Image newImage = new Image(display, imageData);\r
+\r
+               this.setBackgroundImage(newImage);\r
+               SWTGraphicUtil.dispose(this.oldImage);\r
+               this.oldImage = newImage;\r
+       }\r
+\r
+       /**\r
+        * Create a brushed metal background\r
+        * \r
+        * @param width width of the panel\r
+        * @param height height of the panel\r
+        * @return an image data that contains the background\r
+        */\r
+       private ImageData drawBrushedMetalBackground(final int width, final int height) {\r
+\r
+               final int[] inPixels = new int[width];\r
+               final PaletteData palette = new PaletteData(0xFF0000, 0x00FF00, 0x0000FF);\r
+               final ImageData data = new ImageData(width, height, 0x20, palette);\r
+\r
+               this.randomNumbers = new Random(0);\r
+               final int a = this.color & 0xff000000;\r
+               final int r = this.color >> 16 & 0xff;\r
+               final int g = this.color >> 8 & 0xff;\r
+               final int b = this.color & 0xff;\r
+               for (int y = 0; y < height; y++) {\r
+                       for (int x = 0; x < width; x++) {\r
+                               int tr = r;\r
+                               int tg = g;\r
+                               int tb = b;\r
+                               if (this.shine != 0) {\r
+                                       final int f = (int) (255 * this.shine * Math.sin((double) x / width * Math.PI));\r
+                                       tr += f;\r
+                                       tg += f;\r
+                                       tb += f;\r
+                               }\r
+                               if (this.monochrome) {\r
+                                       final int n = (int) (255 * (2 * this.randomNumbers.nextFloat() - 1) * this.amount);\r
+                                       inPixels[x] = a | this.clamp(tr + n) << 16 | this.clamp(tg + n) << 8 | this.clamp(tb + n);\r
+                               } else {\r
+                                       inPixels[x] = a | this.random(tr) << 16 | this.random(tg) << 8 | this.random(tb);\r
+                               }\r
+                       }\r
+\r
+                       if (this.radius != 0) {\r
+                               this.setDataElements(data, palette, 0, y, width, 1, this.blur(inPixels, width, this.radius));\r
+                       } else {\r
+                               this.setDataElements(data, palette, 0, y, width, 1, inPixels);\r
+                       }\r
+               }\r
+\r
+               return data;\r
+       }\r
+\r
+       /**\r
+        * Sets the data for a rectangle of pixels from a primitive array\r
+        * \r
+        * @param data the source ImageData\r
+        * @param palette the palette associated to the imageData\r
+        * @param posX The X coordinate of the upper left pixel location.\r
+        * @param posY The Y coordinate of the upper left pixel location.\r
+        * @param width Width of the pixel rectangle.\r
+        * @param height Height of the pixel rectangle\r
+        * @param pixels An array containing the pixel data to place between x,y and\r
+        *            x+w-1, y+h-1.\r
+        */\r
+       private void setDataElements(final ImageData data, final PaletteData palette, final int posX, final int posY, final int width, final int height, final int[] pixels) {\r
+               int cpt = 0;\r
+               for (int y = posY; y < posY + height; y++) {\r
+                       for (int x = posX; x < posX + width; x++) {\r
+                               final int rgb = pixels[cpt++];\r
+                               final int pixel = palette.getPixel(new RGB(rgb >> 16 & 0xFF, rgb >> 8 & 0xFF, rgb & 0xFF));\r
+                               data.setPixel(x, y, pixel);\r
+                               data.setAlpha(x, y, rgb >> 24 & 0xFF);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Add a random number to the value. The result is between 0 and 255\r
+        * \r
+        * @param x the initial value\r
+        * @return\r
+        */\r
+       private int random(int x) {\r
+               x += (int) (255 * (2 * this.randomNumbers.nextFloat() - 1) * this.amount);\r
+               if (x < 0) {\r
+                       x = 0;\r
+               } else if (x > 0xff) {\r
+                       x = 0xff;\r
+               }\r
+               return x;\r
+       }\r
+\r
+       /**\r
+        * Clamp a number between 0 and 255\r
+        * \r
+        * @param c the number to clamp\r
+        * @return the number. If c is negative, returns 0. If c is greater than\r
+        *         255, returns 255.\r
+        */\r
+       private int clamp(final int c) {\r
+               if (c < 0) {\r
+                       return 0;\r
+               }\r
+\r
+               if (c > 255) {\r
+                       return 255;\r
+               }\r
+\r
+               return c;\r
+       }\r
+\r
+       /**\r
+        * Apply a blur filter to an array of int that represents and image which\r
+        * size is width columns * 1 row\r
+        * \r
+        * @param in the array of int that represents the image\r
+        * @param width the width of the image\r
+        * @param radius the "radius" blur parameter\r
+        */\r
+       private int[] blur(final int[] in, final int width, final int radius) {\r
+               final int[] out = new int[width];\r
+               final int widthMinus1 = width - 1;\r
+               final int r2 = 2 * radius + 1;\r
+               int tr = 0, tg = 0, tb = 0;\r
+\r
+               for (int i = -radius; i <= radius; i++) {\r
+                       final int rgb = in[this.mod(i, width)];\r
+                       tr += rgb >> 16 & 0xff;\r
+                       tg += rgb >> 8 & 0xff;\r
+                       tb += rgb & 0xff;\r
+               }\r
+\r
+               for (int x = 0; x < width; x++) {\r
+                       out[x] = 0xff000000 | tr / r2 << 16 | tg / r2 << 8 | tb / r2;\r
+\r
+                       int i1 = x + radius + 1;\r
+                       if (i1 > widthMinus1) {\r
+                               i1 = this.mod(i1, width);\r
+                       }\r
+                       int i2 = x - radius;\r
+                       if (i2 < 0) {\r
+                               i2 = this.mod(i2, width);\r
+                       }\r
+                       final int rgb1 = in[i1];\r
+                       final int rgb2 = in[i2];\r
+\r
+                       tr += (rgb1 & 0xff0000) - (rgb2 & 0xff0000) >> 16;\r
+                       tg += (rgb1 & 0xff00) - (rgb2 & 0xff00) >> 8;\r
+                       tb += (rgb1 & 0xff) - (rgb2 & 0xff);\r
+               }\r
+               return out;\r
+       }\r
+\r
+       /**\r
+        * Return a mod b. This differs from the % operator with respect to negative\r
+        * numbers.\r
+        * \r
+        * @param a the dividend\r
+        * @param b the divisor\r
+        * @return a mod b\r
+        */\r
+       private int mod(int a, final int b) {\r
+               final int n = a / b;\r
+\r
+               a -= n * b;\r
+               if (a < 0) {\r
+                       return a + b;\r
+               }\r
+               return a;\r
+       }\r
+\r
+       // ------------------------------------ Getters and Setters\r
+\r
+       /**\r
+        * @return the "radius" of the blur\r
+        */\r
+       public int getRadius() {\r
+               return this.radius;\r
+       }\r
+\r
+       /**\r
+        * @param radius the "radius" of the blur\r
+        */\r
+       public void setRadius(final int radius) {\r
+               this.radius = radius;\r
+               this.redrawComposite();\r
+       }\r
+\r
+       /**\r
+        * @return the amount of noise to add\r
+        */\r
+       public float getAmount() {\r
+               return this.amount;\r
+       }\r
+\r
+       /**\r
+        * @param amount the amount of noise to add\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the value is not between 0\r
+        *                and 1 inclusive</li>\r
+        *                </ul>\r
+        */\r
+       public void setAmount(final float amount) {\r
+               if (amount < 0f || amount > 1f) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+               this.amount = amount;\r
+               this.redrawComposite();\r
+       }\r
+\r
+       /**\r
+        * @return the color of the metal. Please notice that this color is a new\r
+        *         SWT object, so it has to be disposed !\r
+        */\r
+       public Color getColor() {\r
+               return new Color(this.getDisplay(), this.color >> 16 & 0xFF, this.color >> 8 & 0xFF, this.color & 0xFF);\r
+       }\r
+\r
+       /**\r
+        * @param color the color to set\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the value is null</li>\r
+        *                </ul>\r
+        */\r
+       public void setColor(final Color color) {\r
+               if (color == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               this.color = 0xFF << 24 | color.getRed() << 16 | color.getGreen() << 8 | color.getBlue();\r
+               this.redrawComposite();\r
+       }\r
+\r
+       /**\r
+        * @return the shine to add\r
+        */\r
+       public float getShine() {\r
+               return this.shine;\r
+       }\r
+\r
+       /**\r
+        * @param shine the shine to set\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the value is not between 0\r
+        *                and 1 inclusive</li>\r
+        *                </ul>\r
+        */\r
+       public void setShine(final float shine) {\r
+               if (this.amount < 0f || this.amount > 1f) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+               this.shine = shine;\r
+               this.redrawComposite();\r
+       }\r
+\r
+       /**\r
+        * @return the monochrome\r
+        */\r
+       public boolean isMonochrome() {\r
+               return this.monochrome;\r
+       }\r
+\r
+       /**\r
+        * @param monochrome the monochrome to set\r
+        */\r
+       public void setMonochrome(final boolean monochrome) {\r
+               this.monochrome = monochrome;\r
+               this.redrawComposite();\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/checkBoxGroup/CheckBoxGroup.java b/org.tizen.common.externals/src/org/mihalis/opal/checkBoxGroup/CheckBoxGroup.java
new file mode 100644 (file)
index 0000000..d8ec1e3
--- /dev/null
@@ -0,0 +1,323 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.checkBoxGroup;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Layout;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class provide an etched border with a title and a checkbox.\r
+ * If the checkbox is checked, the content of the composite is enabled. If the\r
+ * checkbox is unchecked, the content of the composite is disabled, thus not\r
+ * editable.\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>BORDER</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * </dl>\r
+ */\r
+public class CheckBoxGroup extends Composite {\r
+       private Image oldImage;\r
+       protected final Button button;\r
+       private final Composite content;\r
+       private final List<SelectionListener> selectionListeners;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a widget which will be the parent of the new instance\r
+        *            (cannot be null)\r
+        * @param style the style of widget to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        * @see Composite#Composite(Composite, int)\r
+        * @see SWT#BORDER\r
+        * @see Widget#getStyle\r
+        */\r
+       public CheckBoxGroup(final Composite parent, final int style) {\r
+               super(parent, style);\r
+               super.setLayout(new GridLayout());\r
+               this.selectionListeners = new ArrayList<SelectionListener>();\r
+\r
+               this.button = new Button(this, SWT.CHECK);\r
+               final GridData gdButton = new GridData(GridData.BEGINNING, GridData.CENTER, true, false);\r
+               gdButton.horizontalIndent = 15;\r
+               this.button.setLayoutData(gdButton);\r
+               this.button.setSelection(true);\r
+               this.button.setBackground(this.getBackground());\r
+               this.button.pack();\r
+\r
+               this.button.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               e.doit = fireSelectionListeners(e);\r
+                               if (!e.doit) {\r
+                                       return;\r
+                               }\r
+                               if (CheckBoxGroup.this.button.getSelection()) {\r
+                                       CheckBoxGroup.this.activate();\r
+                               } else {\r
+                                       CheckBoxGroup.this.deactivate();\r
+                               }\r
+                       }\r
+               });\r
+\r
+               this.content = new Composite(this, SWT.NONE);\r
+               this.content.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));\r
+\r
+               this.addListener(SWT.Resize, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               CheckBoxGroup.this.drawWidget();\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Fire the selection listeners\r
+        * \r
+        * @param selectionEvent mouse event\r
+        * @return true if the selection could be changed, false otherwise\r
+        */\r
+       private boolean fireSelectionListeners(final SelectionEvent selectionEvent) {\r
+               selectionEvent.widget = this;\r
+               for (final SelectionListener listener : this.selectionListeners) {\r
+                       listener.widgetSelected(selectionEvent);\r
+                       if (!selectionEvent.doit) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Draws the widget\r
+        */\r
+       private void drawWidget() {\r
+               final Display display = this.getDisplay();\r
+               final Rectangle rect = this.getClientArea();\r
+               final Image newImage = new Image(display, Math.max(1, rect.width), Math.max(1, rect.height));\r
+\r
+               final GC gc = new GC(newImage);\r
+               gc.setBackground(this.getBackground());\r
+\r
+               gc.fillRectangle(0, 0, rect.width, rect.height);\r
+\r
+               final int margin = (int) (this.button.getSize().y * 1.5);\r
+               final int startY = margin / 2;\r
+\r
+               gc.setForeground(this.getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));\r
+               gc.drawRoundRectangle(1, startY, rect.width - 2, rect.height - startY - 2, 2, 2);\r
+\r
+               gc.setForeground(this.getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));\r
+               gc.drawRoundRectangle(2, startY + 1, rect.width - 4, rect.height - startY - 4, 2, 2);\r
+\r
+               gc.dispose();\r
+\r
+               this.setBackgroundImage(newImage);\r
+               if (this.oldImage != null) {\r
+                       this.oldImage.dispose();\r
+               }\r
+               this.oldImage = newImage;\r
+\r
+       }\r
+\r
+       /**\r
+        * Activate the content\r
+        */\r
+       public void activate() {\r
+               this.button.setSelection(true);\r
+               SWTGraphicUtil.enable(this.content, true);\r
+       }\r
+\r
+       /**\r
+        * Adds the listener to the collection of listeners who will be notified\r
+        * when the user changes the receiver's selection, by sending it one of the\r
+        * messages defined in the <code>SelectionListener</code> interface.\r
+        * <p>\r
+        * When <code>widgetSelected</code> is called, the item field of the event\r
+        * object is valid. If the receiver has the <code>SWT.CHECK</code> style and\r
+        * the check selection changes, the event object detail field contains the\r
+        * value <code>SWT.CHECK</code>. <code>widgetDefaultSelected</code> is\r
+        * typically called when an item is double-clicked. The item field of the\r
+        * event object is valid for default selection, but the detail field is not\r
+        * used.\r
+        * </p>\r
+        * \r
+        * @param listener the listener which should be notified when the user\r
+        *            changes the receiver's selection\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #removeSelectionListener\r
+        * @see SelectionEvent\r
+        */\r
+       public void addSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               this.selectionListeners.add(listener);\r
+       }\r
+\r
+       /**\r
+        * Deactivate the content\r
+        */\r
+       public void deactivate() {\r
+               this.button.setSelection(false);\r
+               SWTGraphicUtil.enable(this.content, false);\r
+       }\r
+\r
+       /**\r
+        * @return <code>true</code> if the content is activated, <code>false</code>\r
+        *         otherwise\r
+        */\r
+       public boolean isActivated() {\r
+               return this.button.getSelection();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#getLayout()\r
+        */\r
+       @Override\r
+       public Layout getLayout() {\r
+               return this.content.getLayout();\r
+       }\r
+\r
+       /**\r
+        * Removes the listener from the collection of listeners who will be\r
+        * notified when the user changes the receiver's selection.\r
+        * \r
+        * @param listener the listener which should no longer be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #addSelectionListener\r
+        */\r
+       public void removeSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               this.selectionListeners.remove(listener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#setFocus()\r
+        */\r
+       @Override\r
+       public boolean setFocus() {\r
+               return this.content.setFocus();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#setLayout(org.eclipse.swt.widgets.Layout)\r
+        */\r
+       @Override\r
+       public void setLayout(final Layout layout) {\r
+               this.content.setLayout(layout);\r
+       }\r
+\r
+       // ------------------------------------ Getters and Setters\r
+\r
+       /**\r
+        * @return the text of the button\r
+        */\r
+       public String getText() {\r
+               return this.button.getText();\r
+       }\r
+\r
+       /**\r
+        * @param text the text of the button to set\r
+        */\r
+       public void setText(final String text) {\r
+               this.button.setText(text);\r
+       }\r
+\r
+       /**\r
+        * @return the font of the button\r
+        */\r
+       @Override\r
+       public Font getFont() {\r
+               return this.button.getFont();\r
+       }\r
+\r
+       /**\r
+        * @param font the font to set\r
+        */\r
+       @Override\r
+       public void setFont(final Font font) {\r
+               this.button.setFont(font);\r
+       }\r
+\r
+       /**\r
+        * @return the content of the group\r
+        */\r
+       public Composite getContent() {\r
+               return this.content;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnBrowserWidget.java b/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnBrowserWidget.java
new file mode 100755 (executable)
index 0000000..991f6a2
--- /dev/null
@@ -0,0 +1,785 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.columns;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.custom.ScrolledComposite;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Cursor;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.RowData;\r
+import org.eclipse.swt.layout.RowLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Menu;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class provide a data browser similar to the ones used in\r
+ * Mac OS X. Look at http://en.wikipedia.org/wiki/Miller_Columns\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>BORDER</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>Selection</dd>\r
+ * </dl>\r
+ */\r
+public class ColumnBrowserWidget extends ScrolledComposite {\r
+\r
+       private final List<Table> columns;\r
+       private final Composite composite;\r
+       private final Image columnArrow;\r
+       private final List<SelectionListener> selectionListeners;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a widget which will be the parent of the new instance\r
+        *            (cannot be null)\r
+        * @param style the style of widget to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        * @see Composite#Composite(Composite, int)\r
+        * @see SWT#BORDER\r
+        * @see Widget#getStyle\r
+        */\r
+       public ColumnBrowserWidget(final Composite parent, final int style) {\r
+               super(parent, style | SWT.H_SCROLL | SWT.V_SCROLL);\r
+\r
+               this.composite = new Composite(this, SWT.NONE);\r
+               final RowLayout layout = new RowLayout(SWT.HORIZONTAL);\r
+               layout.spacing = 1;\r
+               layout.pack = false;\r
+               this.composite.setLayout(layout);\r
+\r
+               this.columnArrow = SWTGraphicUtil.createImage("images/columnArrow.png");\r
+\r
+               this.columns = new ArrayList<Table>();\r
+               for (int i = 0; i < 3; i++) {\r
+                       this.createTable();\r
+               }\r
+\r
+               // Store root\r
+               this.columns.get(0).setData(new ColumnItem(this));\r
+\r
+               this.setContent(this.composite);\r
+               this.setExpandHorizontal(true);\r
+               this.setExpandVertical(true);\r
+               this.setShowFocusedControl(true);\r
+               this.updateContent();\r
+               this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
+\r
+               this.selectionListeners = new ArrayList<SelectionListener>();\r
+\r
+               this.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent arg0) {\r
+                               SWTGraphicUtil.dispose(ColumnBrowserWidget.this.columnArrow);\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Create a column that displays data\r
+        */\r
+       private void createTable() {\r
+               final Table table = new Table(this.composite, SWT.SINGLE | SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);\r
+               new TableColumn(table, SWT.LEFT);\r
+\r
+               table.setLayoutData(new RowData(150, 175));\r
+               this.columns.add(table);\r
+\r
+               table.addListener(SWT.Resize, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final int width = table.getSize().x;\r
+                               table.getColumn(0).setWidth(width - 5);\r
+                       }\r
+               });\r
+\r
+               table.addListener(SWT.Selection, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final Table table = (Table) event.widget;\r
+                               if (table.getSelection() == null || table.getSelection().length != 1) {\r
+                                       return;\r
+                               }\r
+                               ColumnBrowserWidget.this.selectItem(table.getSelection()[0]);\r
+                       }\r
+               });\r
+\r
+               final Listener paintListener = new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               switch (event.type) {\r
+                               case SWT.MeasureItem: {\r
+                                       final Rectangle rect = ColumnBrowserWidget.this.columnArrow.getBounds();\r
+                                       event.width += rect.width;\r
+                                       event.height = Math.max(event.height, rect.height + 2);\r
+                                       break;\r
+                               }\r
+\r
+                               case SWT.PaintItem: {\r
+                                       if (!(event.item instanceof TableItem)) {\r
+                                               return;\r
+                                       }\r
+                                       final TableItem item = (TableItem) event.item;\r
+                                       if (item.getData() == null) {\r
+                                               return;\r
+                                       }\r
+\r
+                                       if (((ColumnItem) item.getData()).getItemCount() == 0) {\r
+                                               return;\r
+                                       }\r
+\r
+                                       final int x = event.x + event.width;\r
+                                       final Rectangle rect = ColumnBrowserWidget.this.columnArrow.getBounds();\r
+                                       final int offset = Math.max(0, (event.height - rect.height) / 2);\r
+                                       event.gc.drawImage(ColumnBrowserWidget.this.columnArrow, x, event.y + offset);\r
+                                       break;\r
+                               }\r
+                               default:\r
+                                   break;\r
+                               }\r
+                       }\r
+               };\r
+               table.addListener(SWT.MeasureItem, paintListener);\r
+               table.addListener(SWT.PaintItem, paintListener);\r
+\r
+               table.addSelectionListener(new SelectionListener() {\r
+\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               ColumnBrowserWidget.this.fireSelectionListeners(e);\r
+                       }\r
+\r
+                       @Override\r
+                       public void widgetDefaultSelected(final SelectionEvent e) {\r
+                               ColumnBrowserWidget.this.fireSelectionListeners(e);\r
+                       }\r
+               });\r
+\r
+               if (super.getBackground() != null && super.getBackground().getRed() != 240 && super.getBackground().getGreen() != 240 && super.getBackground().getBlue() != 240) {\r
+                       table.setBackground(super.getBackground());\r
+               }\r
+               table.setBackgroundImage(super.getBackgroundImage());\r
+               table.setBackgroundMode(super.getBackgroundMode());\r
+               table.setCursor(super.getCursor());\r
+               table.setFont(super.getFont());\r
+               table.setForeground(super.getForeground());\r
+               table.setMenu(super.getMenu());\r
+               table.setToolTipText(super.getToolTipText());\r
+\r
+       }\r
+\r
+       /**\r
+        * Fire the selection listeners\r
+        * \r
+        * @param selectionEvent mouse event\r
+        * @return true if the selection could be changed, false otherwise\r
+        */\r
+       private boolean fireSelectionListeners(final SelectionEvent selectionEvent) {\r
+               for (final SelectionListener listener : this.selectionListeners) {\r
+                       final Event event = new Event();\r
+\r
+                       event.button = 0;\r
+                       event.display = this.getDisplay();\r
+                       event.item = null;\r
+                       event.widget = this;\r
+                       event.data = null;\r
+                       event.time = selectionEvent.time;\r
+                       event.x = selectionEvent.x;\r
+                       event.y = selectionEvent.y;\r
+\r
+                       final SelectionEvent selEvent = new SelectionEvent(event);\r
+                       listener.widgetSelected(selEvent);\r
+                       if (!selEvent.doit) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Perform actions when an item is selected (ie fill the next column and\r
+        * force focus on it)\r
+        * \r
+        * @param tableItem selected item\r
+        */\r
+       private void selectItem(final TableItem tableItem) {\r
+               final ColumnItem c = (ColumnItem) tableItem.getData();\r
+\r
+               if (c.getItemCount() == 0) {\r
+                       return;\r
+               }\r
+\r
+               final int selectedColumn = this.findSelectedColumn(tableItem);\r
+               boolean needPacking = false;\r
+               if (selectedColumn != this.columns.size() - 1) {\r
+                       for (int i = selectedColumn + 1; i < this.columns.size(); i++) {\r
+                               this.columns.get(i).setData(null);\r
+                               this.columns.get(i).deselectAll();\r
+                       }\r
+\r
+                       int i = 0;\r
+                       final Iterator<Table> it = this.columns.iterator();\r
+                       while (it.hasNext()) {\r
+                               final Table t = it.next();\r
+                               if (i >= 3) {\r
+                                       t.dispose();\r
+                                       it.remove();\r
+                                       // Don't know why, it's not working if I do not include this\r
+                                       // :(\r
+                                       this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
+                               }\r
+                               i++;\r
+                       }\r
+\r
+                       if (selectedColumn != this.columns.size() - 1) {\r
+                               this.columns.get(selectedColumn + 1).setData(c);\r
+                       } else {\r
+                               this.createTable();\r
+                               this.columns.get(this.columns.size() - 1).setData(c);\r
+                       }\r
+                       needPacking = true;\r
+\r
+               } else {\r
+                       this.createTable();\r
+                       needPacking = true;\r
+                       this.columns.get(this.columns.size() - 1).setData(c);\r
+               }\r
+               this.updateContent();\r
+               if (needPacking) {\r
+                       this.composite.pack();\r
+                       this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
+               }\r
+               this.columns.get(this.columns.size() - 1).forceFocus();\r
+       }\r
+\r
+       /**\r
+        * Find which column has been selected\r
+        * \r
+        * @param tableItem selected table item\r
+        * @return the index of the selected column\r
+        */\r
+       private int findSelectedColumn(final TableItem tableItem) {\r
+               for (int i = 0; i < this.columns.size(); i++) {\r
+                       if (this.columns.get(i).equals(tableItem.getParent())) {\r
+                               return i;\r
+                       }\r
+               }\r
+               return -1;\r
+       }\r
+\r
+       /**\r
+        * Update the content of the widget\r
+        */\r
+       void updateContent() {\r
+               if (this.columns == null) {\r
+                       return;\r
+               }\r
+\r
+               for (int i = 0; i < this.columns.size(); i++) {\r
+\r
+                       final Table table = this.columns.get(i);\r
+                       final int index = table.getSelectionIndex();\r
+                       table.removeAll();\r
+                       if (table.getData() == null) {\r
+                               continue;\r
+                       }\r
+                       for (final ColumnItem c : ((ColumnItem) table.getData()).getItems()) {\r
+                               final TableItem item = new TableItem(table, SWT.NONE);\r
+                               item.setData(c);\r
+                               if (c.getText() != null) {\r
+                                       item.setText(c.getText());\r
+                               }\r
+                               if (c.getImage() != null) {\r
+                                       item.setImage(c.getImage());\r
+                               }\r
+                       }\r
+                       table.setSelection(index);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Adds the listener to the collection of listeners who will be notified\r
+        * when the user changes the receiver's selection, by sending it one of the\r
+        * messages defined in the <code>SelectionListener</code> interface.\r
+        * <p>\r
+        * When <code>widgetSelected</code> is called, the item field of the event\r
+        * object is valid. If the receiver has the <code>SWT.CHECK</code> style and\r
+        * the check selection changes, the event object detail field contains the\r
+        * value <code>SWT.CHECK</code>. <code>widgetDefaultSelected</code> is\r
+        * typically called when an item is double-clicked. The item field of the\r
+        * event object is valid for default selection, but the detail field is not\r
+        * used.\r
+        * </p>\r
+        * \r
+        * @param listener the listener which should be notified when the user\r
+        *            changes the receiver's selection\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #removeSelectionListener\r
+        * @see SelectionEvent\r
+        */\r
+       public void addSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               this.selectionListeners.add(listener);\r
+       }\r
+\r
+       /**\r
+        * Clear the selection\r
+        * \r
+        * @param needPacking if <code>true</code>, the widget is packed\r
+        */\r
+       public void clear(final boolean needPacking) {\r
+               final Iterator<Table> it = this.columns.iterator();\r
+               int i = 0;\r
+               while (it.hasNext()) {\r
+                       final Table t = it.next();\r
+                       if (i >= 3) {\r
+                               t.dispose();\r
+                               it.remove();\r
+                       } else {\r
+                               if (i != 0) {\r
+                                       t.setData(null);\r
+                               }\r
+                               t.deselectAll();\r
+                       }\r
+                       i++;\r
+               }\r
+               this.updateContent();\r
+               if (needPacking) {\r
+                       this.composite.pack();\r
+                       this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
+               }\r
+               this.columns.get(0).forceFocus();\r
+       }\r
+\r
+       /**\r
+        * Returns the <code>ColumnItem</code>s that is currently selected in the\r
+        * receiver.\r
+        * \r
+        * @return the selected item, or <code>null</code> if no one is selected\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public ColumnItem getSelection() {\r
+               for (int i = this.columns.size() - 1; i >= 0; i--) {\r
+                       final Table table = this.columns.get(i);\r
+                       if (table == null || table.getData() == null || table.getSelection().length == 0) {\r
+                               continue;\r
+                       }\r
+\r
+                       return (ColumnItem) table.getItem(table.getSelectionIndex()).getData();\r
+\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Removes the listener from the collection of listeners who will be\r
+        * notified when the user changes the receiver's selection.\r
+        * \r
+        * @param listener the listener which should no longer be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #addSelectionListener\r
+        */\r
+       public void removeSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               this.selectionListeners.remove(listener);\r
+       }\r
+\r
+       /**\r
+        * Selects an item in the receiver. If the item was already selected, it\r
+        * remains selected.\r
+        * \r
+        * @param item the item to be selected\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the item is null</li>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the item has been disposed\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void select(final ColumnItem item) {\r
+\r
+               final List<ColumnItem> items = new ArrayList<ColumnItem>();\r
+               this.findElement(item, items);\r
+               Collections.reverse(items);\r
+               if (items.isEmpty()) {\r
+                       return;\r
+               }\r
+\r
+               this.clear(false);\r
+               for (int i = 3; i < items.size(); i++) {\r
+                       this.createTable();\r
+               }\r
+               for (int i = 0; i < items.size() - 1; i++) {\r
+                       this.columns.get(i + 1).setData(items.get(i));\r
+               }\r
+               this.updateContent();\r
+\r
+               for (int i = 0; i < this.columns.size() - 1; i++) {\r
+                       final ColumnItem nextItem = (ColumnItem) this.columns.get(i + 1).getData();\r
+                       for (final TableItem tableItem : this.columns.get(i).getItems()) {\r
+                               if (tableItem.getData() != null && tableItem.getData().equals(nextItem)) {\r
+                                       tableItem.getParent().setSelection(tableItem);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               this.composite.pack();\r
+               this.setMinSize(this.composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
+               this.columns.get(this.columns.size() - 1).forceFocus();\r
+\r
+       }\r
+\r
+       /**\r
+        * Build an array that contains the hierarchy of ColumnItem from the root\r
+        * node to a given item.\r
+        * \r
+        * @param item item to find\r
+        * @param items the lists of item that composes the hierarchy\r
+        */\r
+       private void findElement(final ColumnItem item, final List<ColumnItem> items) {\r
+               if (item == null) {\r
+                       return;\r
+               }\r
+               items.add(item);\r
+               this.findElement(item.getParentItem(), items);\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's background color to the color specified by the\r
+        * argument, or to the default system color for the control if the argument\r
+        * is null.\r
+        * <p>\r
+        * Note: This operation is a hint and may be overridden by the platform. For\r
+        * example, on Windows the background of a Button cannot be changed.\r
+        * </p>\r
+        * \r
+        * @param color the new color (or null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the argument has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color)\r
+        */\r
+       @Override\r
+       public void setBackground(final Color color) {\r
+               super.setBackground(color);\r
+               for (final Table column : this.columns) {\r
+                       column.setBackground(color);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Sets the background drawing mode to the argument which should be one of\r
+        * the following constants defined in class <code>SWT</code>:\r
+        * <code>INHERIT_NONE</code>, <code>INHERIT_DEFAULT</code>,\r
+        * <code>INHERIT_FORCE</code>.\r
+        * \r
+        * @param mode the new background mode\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SWT\r
+        * @see org.eclipse.swt.widgets.Composite#setBackgroundMode(int)\r
+        */\r
+       @Override\r
+       public void setBackgroundMode(final int mode) {\r
+               super.setBackgroundMode(mode);\r
+               for (final Table column : this.columns) {\r
+                       column.setBackgroundMode(mode);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's background image to the image specified by the\r
+        * argument, or to the default system color for the control if the argument\r
+        * is null. The background image is tiled to fill the available space.\r
+        * <p>\r
+        * Note: This operation is a hint and may be overridden by the platform. For\r
+        * example, on Windows the background of a Button cannot be changed.\r
+        * </p>\r
+        * \r
+        * @param image the new image (or null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the argument has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the argument is not a\r
+        *                bitmap</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see org.eclipse.swt.widgets.Control#setBackgroundImage(org.eclipse.swt.graphics.Image)\r
+        */\r
+       @Override\r
+       public void setBackgroundImage(final Image image) {\r
+               super.setBackgroundImage(image);\r
+               for (final Table column : this.columns) {\r
+                       column.setBackgroundImage(image);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's cursor to the cursor specified by the argument, or to\r
+        * the default cursor for that kind of control if the argument is null.\r
+        * <p>\r
+        * When the mouse pointer passes over a control its appearance is changed to\r
+        * match the control's cursor.\r
+        * </p>\r
+        * \r
+        * @param cursor the new cursor (or null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the argument has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * @see org.eclipse.swt.widgets.Control#setCursor(org.eclipse.swt.graphics.Cursor)\r
+        */\r
+       @Override\r
+       public void setCursor(final Cursor cursor) {\r
+               super.setCursor(cursor);\r
+               for (final Table column : this.columns) {\r
+                       column.setCursor(cursor);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Sets the font that the receiver will use to paint textual information to\r
+        * the font specified by the argument, or to the default font for that kind\r
+        * of control if the argument is null.\r
+        * \r
+        * @param font the new font (or null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the argument has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font)\r
+        */\r
+       @Override\r
+       public void setFont(final Font font) {\r
+               super.setFont(font);\r
+               for (final Table column : this.columns) {\r
+                       column.setFont(font);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's foreground color to the color specified by the\r
+        * argument, or to the default system color for the control if the argument\r
+        * is null.\r
+        * <p>\r
+        * Note: This operation is a hint and may be overridden by the platform.\r
+        * </p>\r
+        * \r
+        * @param color the new color (or null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the argument has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color)\r
+        */\r
+       @Override\r
+       public void setForeground(final Color color) {\r
+               super.setForeground(color);\r
+               for (final Table column : this.columns) {\r
+                       column.setForeground(color);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's pop up menu to the argument. All controls may\r
+        * optionally have a pop up menu that is displayed when the user requests\r
+        * one for the control. The sequence of key strokes, button presses and/or\r
+        * button releases that are used to request a pop up menu is platform\r
+        * specific.\r
+        * <p>\r
+        * Note: Disposing of a control that has a pop up menu will dispose of the\r
+        * menu. To avoid this behavior, set the menu to null before the control is\r
+        * disposed.\r
+        * </p>\r
+        * \r
+        * @param menu the new pop up menu\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li>\r
+        *                <li>ERROR_INVALID_PARENT - if the menu is not in the same\r
+        *                widget tree</li>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu)\r
+        */\r
+       @Override\r
+       public void setMenu(final Menu menu) {\r
+               super.setMenu(menu);\r
+               for (final Table column : this.columns) {\r
+                       column.setMenu(menu);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's tool tip text to the argument, which may be null\r
+        * indicating that the default tool tip for the control will be shown. For a\r
+        * control that has a default tool tip, such as the Tree control on Windows,\r
+        * setting the tool tip text to an empty string replaces the default,\r
+        * causing no tool tip text to be shown.\r
+        * <p>\r
+        * The mnemonic indicator (character '&amp;') is not displayed in a tool\r
+        * tip. To display a single '&amp;' in the tool tip, the character '&amp;'\r
+        * can be escaped by doubling it in the string.\r
+        * </p>\r
+        * \r
+        * @param string the new tool tip text (or null)\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String)\r
+        */\r
+       @Override\r
+       public void setToolTipText(final String tooltipText) {\r
+               super.setToolTipText(tooltipText);\r
+               for (final Table column : this.columns) {\r
+                       column.setToolTipText(tooltipText);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return the root item, or null if there is no data\r
+        */\r
+       ColumnItem getRootItem() {\r
+               if (this.columns == null || this.columns.isEmpty()) {\r
+                       return null;\r
+               }\r
+               return (ColumnItem) this.columns.get(0).getData();\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnItem.java b/org.tizen.common.externals/src/org/mihalis/opal/columns/ColumnItem.java
new file mode 100644 (file)
index 0000000..52d63fa
--- /dev/null
@@ -0,0 +1,416 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.columns;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.mihalis.opal.OpalItem;\r
+\r
+/**\r
+ * Instances of this object are items manipulated by the ColumnBrowser widget.\r
+ * ColumnItems are part of a tree structure .\r
+ * \r
+ * @see OpalItem\r
+ */\r
+public class ColumnItem extends OpalItem {\r
+\r
+       private final ColumnBrowserWidget widget;\r
+       private final ColumnItem parent;\r
+       private final List<ColumnItem> children;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent. The item is\r
+        * added to the end of the items maintained by its parent.\r
+        * \r
+        * @param widget the widget that will contain this item (can not be null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public ColumnItem(final ColumnBrowserWidget widget) {\r
+               if (widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               this.widget = widget;\r
+               this.parent = null;\r
+               this.children = new ArrayList<ColumnItem>();\r
+\r
+               if (widget.getRootItem() != null) {\r
+                       widget.getRootItem().children.add(this);\r
+               }\r
+               widget.updateContent();\r
+       }\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent. The item is\r
+        * added at a given position in the items'list maintained by its parent.\r
+        * \r
+        * @param widget the widget that will contain this item (can not be null)\r
+        * @param index the position\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public ColumnItem(final ColumnBrowserWidget widget, final int index) {\r
+\r
+               if (widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               this.widget = widget;\r
+               this.parent = null;\r
+               this.children = new ArrayList<ColumnItem>();\r
+               widget.getRootItem().children.add(index, this);\r
+               widget.updateContent();\r
+       }\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent. The item is\r
+        * added to the end of the items maintained by its parent.\r
+        * \r
+        * @param widget the widget that will contain this item (can not be null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public ColumnItem(final ColumnItem parent) {\r
+\r
+               if (parent == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (parent.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               this.widget = parent.widget;\r
+               this.parent = parent;\r
+               this.children = new ArrayList<ColumnItem>();\r
+               parent.children.add(this);\r
+               parent.widget.updateContent();\r
+       }\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent. The item is\r
+        * added at a given position in the items'list maintained by its parent.\r
+        * \r
+        * @param widget the widget that will contain this item (can not be null)\r
+        * @param index the position\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public ColumnItem(final ColumnItem parent, final int index) {\r
+               if (parent == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (parent.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               this.widget = parent.widget;\r
+               this.parent = parent;\r
+               this.children = new ArrayList<ColumnItem>();\r
+               parent.children.add(index, this);\r
+               parent.widget.updateContent();\r
+       }\r
+\r
+       /**\r
+        * Remove a given children of this object\r
+        * \r
+        * @param item the item to remove (can not be null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public void remove(final ColumnItem item) {\r
+               if (this.widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+               this.children.remove(item);\r
+               this.widget.updateContent();\r
+       }\r
+\r
+       /**\r
+        * Remove a children in a given position of this object\r
+        * \r
+        * @param index position of the children in the items'list\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public void remove(final int index) {\r
+               if (this.widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+               this.children.remove(index);\r
+               this.widget.updateContent();\r
+       }\r
+\r
+       /**\r
+        * Remove all children of this object\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public void removeAll() {\r
+               if (this.widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+               this.children.clear();\r
+               this.widget.updateContent();\r
+       }\r
+\r
+       /**\r
+        * Returns an item located at a given position\r
+        * \r
+        * @param index position\r
+        * @return the item located at the index position\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public ColumnItem getItem(final int index) {\r
+               if (this.widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+               return this.children.get(index);\r
+       }\r
+\r
+       /**\r
+        * @return the number of children\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public int getItemCount() {\r
+               if (this.widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+               return this.children.size();\r
+       }\r
+\r
+       /**\r
+        * @return all children of this item\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public ColumnItem[] getItems() {\r
+               if (this.widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+               return this.children.toArray(new ColumnItem[this.children.size()]);\r
+       }\r
+\r
+       /**\r
+        * @return the widget that holds this item\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public ColumnBrowserWidget getParent() {\r
+               if (this.widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+               return this.widget;\r
+       }\r
+\r
+       /**\r
+        * @return the parent item, of <code>null</code> if this item is the root\r
+        *         node\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public ColumnItem getParentItem() {\r
+               if (this.widget == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.widget.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+               return this.parent;\r
+       }\r
+\r
+       /**\r
+        * Return the position of a given item in children's list\r
+        * \r
+        * @param item item to find\r
+        * @return the position of the children, or -1 if <code>item</code> is a not\r
+        *         a children of this object\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        */\r
+       public int indexOf(final ColumnItem item) {\r
+               return this.children.indexOf(item);\r
+       }\r
+\r
+       /**\r
+        * @see java.lang.Object#hashCode()\r
+        */\r
+       @Override\r
+       public int hashCode() {\r
+               final int prime = 31;\r
+               int result = 1;\r
+               result = prime * result + (this.parent == null ? 0 : this.parent.hashCode());\r
+               result = prime * result + (this.widget == null ? 0 : this.widget.hashCode());\r
+               return result;\r
+       }\r
+\r
+       /**\r
+        * @see java.lang.Object#equals(java.lang.Object)\r
+        */\r
+       @Override\r
+       public boolean equals(final Object obj) {\r
+               if (this == obj) {\r
+                       return true;\r
+               }\r
+               if (obj == null) {\r
+                       return false;\r
+               }\r
+               if (getClass() != obj.getClass()) {\r
+                       return false;\r
+               }\r
+               final ColumnItem other = (ColumnItem) obj;\r
+               if (this.children == null) {\r
+                       if (other.children != null) {\r
+                               return false;\r
+                       }\r
+               } else if (!this.children.equals(other.children)) {\r
+                       return false;\r
+               }\r
+               if (this.parent == null) {\r
+                       if (other.parent != null) {\r
+                               return false;\r
+                       }\r
+               } else if (!this.parent.equals(other.parent)) {\r
+                       return false;\r
+               }\r
+               if (this.widget == null) {\r
+                       if (other.widget != null) {\r
+                               return false;\r
+                       }\r
+               } else if (!this.widget.equals(other.widget)) {\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/flatButton/FlatButton.java b/org.tizen.common.externals/src/org/mihalis/opal/flatButton/FlatButton.java
new file mode 100644 (file)
index 0000000..ede14ba
--- /dev/null
@@ -0,0 +1,633 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation \r
+ *******************************************************************************/\r
+package org.mihalis.opal.flatButton;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class represent a flat button.\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * <dd>UP, DOWN, LEFT, RIGHT, CENTER</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>Selection</dd>\r
+ * </dl>\r
+ * <p>\r
+ * Note: Only one of the styles LEFT, RIGHT, and CENTER may be specified.\r
+ * </p>\r
+ * \r
+ */\r
+public class FlatButton extends Canvas {\r
+    private Image image;\r
+    private String text;\r
+    private boolean selection;\r
+    private int alignment;\r
+    private final List<SelectionListener> listeners;\r
+    private boolean mouseIn;\r
+    private Color backgroundColor;\r
+    private Color selectedColor;\r
+    private Color selectedTextColor;\r
+    private Color mouseOverColor;\r
+\r
+    /**\r
+     * Constructs a new instance of this class given its parent and a style\r
+     * value describing its behavior and appearance.\r
+     * <p>\r
+     * The style value is either one of the style constants defined in class\r
+     * <code>SWT</code> which is applicable to instances of this class, or must\r
+     * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+     * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+     * style constants. The class description lists the style constants that are\r
+     * applicable to the class. Style bits are also inherited from superclasses.\r
+     * </p>\r
+     * \r
+     * @param parent a composite control which will be the parent of the new\r
+     *            instance (cannot be null)\r
+     * @param style the style of control to construct\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the parent</li>\r
+     *                <li>ERROR_INVALID_SUBCLASS - if this class is not an\r
+     *                allowed subclass</li>\r
+     *                </ul>\r
+     * \r
+     * @see SWT#DOWN\r
+     * @see SWT#LEFT\r
+     * @see SWT#RIGHT\r
+     * @see SWT#CENTER\r
+     */\r
+    public FlatButton(final Composite parent, final int style) {\r
+        super(parent, style);\r
+        this.listeners = new ArrayList<SelectionListener>();\r
+        buildAlignmentFromStyle(style);\r
+        addListeners();\r
+        initializeDefaultColors();\r
+    }\r
+\r
+    private void buildAlignmentFromStyle(final int style) {\r
+        if ((style & SWT.LEFT) == SWT.LEFT) {\r
+            this.alignment = SWT.LEFT;\r
+        } else if ((style & SWT.RIGHT) == SWT.RIGHT) {\r
+            this.alignment = SWT.RIGHT;\r
+        } else {\r
+            this.alignment = SWT.CENTER;\r
+\r
+        }\r
+    }\r
+\r
+    private void addListeners() {\r
+        addPaintListener(new PaintListener() {\r
+            @Override\r
+            public void paintControl(final PaintEvent e) {\r
+                FlatButton.this.paintControl(e);\r
+            }\r
+        });\r
+\r
+        addListener(SWT.MouseEnter, new Listener() {\r
+            @Override\r
+            public void handleEvent(final Event event) {\r
+                FlatButton.this.mouseIn = true;\r
+                redraw();\r
+            }\r
+        });\r
+\r
+        addListener(SWT.MouseExit, new Listener() {\r
+            @Override\r
+            public void handleEvent(final Event event) {\r
+                FlatButton.this.mouseIn = false;\r
+                redraw();\r
+            }\r
+        });\r
+\r
+        addListener(SWT.MouseUp, new Listener() {\r
+            @Override\r
+            public void handleEvent(final Event event) {\r
+                boolean doIt = true;\r
+                FlatButton.this.selection = !FlatButton.this.selection;\r
+                for (final SelectionListener listener : FlatButton.this.listeners) {\r
+                    final SelectionEvent sEvent = new SelectionEvent(event);\r
+                    listener.widgetSelected(sEvent);\r
+                    doIt = doIt && sEvent.doit;\r
+                }\r
+                if (!doIt) {\r
+                    FlatButton.this.selection = !FlatButton.this.selection;\r
+                }\r
+            }\r
+\r
+        });\r
+    }\r
+\r
+    private void initializeDefaultColors() {\r
+        this.backgroundColor = getDisplay().getSystemColor(SWT.COLOR_WHITE);\r
+        this.selectedColor = new Color(getDisplay(), 0, 112, 192);\r
+        this.selectedTextColor = getDisplay().getSystemColor(SWT.COLOR_WHITE);\r
+        this.mouseOverColor = new Color(getDisplay(), 235, 234, 226);\r
+\r
+        SWTGraphicUtil.dispose(this, this.selectedColor);\r
+        SWTGraphicUtil.dispose(this, this.mouseOverColor);\r
+        SWTGraphicUtil.dispose(this, this.image);\r
+    }\r
+\r
+    private void paintControl(final PaintEvent e) {\r
+        final GC gc = e.gc;\r
+        drawBackground(gc);\r
+        if (this.image != null) {\r
+            drawImage(gc);\r
+        }\r
+        if (this.text != null) {\r
+            drawText(gc);\r
+        }\r
+    }\r
+\r
+    private void drawBackground(final GC gc) {\r
+        Color color;\r
+        if (this.selection) {\r
+            color = this.selectedColor;\r
+        } else if (this.mouseIn) {\r
+            color = this.mouseOverColor;\r
+        } else {\r
+            color = this.backgroundColor;\r
+        }\r
+        gc.setBackground(color);\r
+        gc.fillRectangle(getClientArea());\r
+\r
+    }\r
+\r
+    private void drawImage(final GC gc) {\r
+        final Rectangle rect = getClientArea();\r
+        final Point imageSize = new Point(this.image.getBounds().width, this.image.getBounds().height);\r
+\r
+        int x;\r
+        if (this.alignment == SWT.LEFT) {\r
+            x = 5;\r
+        } else if (this.alignment == SWT.RIGHT) {\r
+            x = rect.width - imageSize.x - 5;\r
+        } else {\r
+            x = (rect.width - imageSize.x) / 2;\r
+        }\r
+        gc.drawImage(this.image, x, 5);\r
+    }\r
+\r
+    private void drawText(final GC gc) {\r
+        final Rectangle rect = getClientArea();\r
+\r
+        if (this.selection) {\r
+            gc.setForeground(this.selectedTextColor);\r
+        } else {\r
+            gc.setForeground(getForeground());\r
+        }\r
+\r
+        gc.setFont(getFont());\r
+        final Point textSize = gc.stringExtent(this.text);\r
+        int x, y;\r
+\r
+        if (this.alignment == SWT.LEFT) {\r
+            x = 5;\r
+        } else if (this.alignment == SWT.RIGHT) {\r
+            x = rect.width - textSize.x - 5;\r
+        } else {\r
+            x = (rect.width - textSize.x) / 2;\r
+        }\r
+        if (this.image == null) {\r
+            y = 5;\r
+        } else {\r
+            y = 10 + this.image.getBounds().height;\r
+        }\r
+        gc.drawString(this.text, x, y, true);\r
+    }\r
+\r
+    /**\r
+     * Adds the listener to the collection of listeners who will be notified\r
+     * when the control is selected by the user, by sending it one of the\r
+     * messages defined in the <code>SelectionListener</code> interface.\r
+     * <p>\r
+     * <code>widgetSelected</code> is called when the control is selected by the\r
+     * user. <code>widgetDefaultSelected</code> is not called.\r
+     * </p>\r
+     * <p>\r
+     * When the <code>SWT.RADIO</code> style bit is set, the\r
+     * <code>widgetSelected</code> method is also called when the receiver loses\r
+     * selection because another item in the same radio group was selected by\r
+     * the user. During <code>widgetSelected</code> the application can use\r
+     * <code>getSelection()</code> to determine the current selected state of\r
+     * the receiver.\r
+     * </p>\r
+     * \r
+     * @param listener the listener which should be notified\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     * @see SelectionListener\r
+     * @see #removeSelectionListener\r
+     * @see SelectionEvent\r
+     */\r
+    public void addSelectionListener(final SelectionListener listener) {\r
+        checkWidget();\r
+        this.listeners.add(listener);\r
+    }\r
+\r
+    /**\r
+     * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)\r
+     */\r
+    @Override\r
+    public Point computeSize(final int wHint, final int hHint, final boolean changed) {\r
+        int width = 10, height = 15;\r
+        if (this.image != null) {\r
+            final Rectangle bounds = this.image.getBounds();\r
+            width += bounds.width;\r
+            height += bounds.height;\r
+        }\r
+\r
+        if (this.text != null) {\r
+            final GC gc = new GC(this);\r
+            final Point extent = gc.stringExtent(this.text);\r
+            gc.dispose();\r
+            width = Math.max(width, extent.x + 10);\r
+            height = height + extent.y;\r
+        }\r
+\r
+        return new Point(Math.max(width, wHint), Math.max(height, hHint));\r
+    }\r
+\r
+    /**\r
+     * Returns a value which describes the position of the text in the receiver.\r
+     * The value will be one of <code>LEFT</code>, <code>RIGHT</code> or\r
+     * <code>CENTER</code>.\r
+     * \r
+     * @return the alignment\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public int getAlignment() {\r
+        checkWidget();\r
+        return this.alignment;\r
+    }\r
+\r
+    /**\r
+     * Returns a value which describes the default background color\r
+     * \r
+     * @return the default background color\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public Color getBackgroundColor() {\r
+        checkWidget();\r
+        return this.backgroundColor;\r
+    }\r
+\r
+    /**\r
+     * Returns the receiver's image if it has one, or null if it does not.\r
+     * \r
+     * @return the receiver's image\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public Image getImage() {\r
+        checkWidget();\r
+        return this.image;\r
+    }\r
+\r
+    /**\r
+     * Returns a value which describes the color when the mouse is over the\r
+     * button\r
+     * \r
+     * @return the color when the mouse is over the button\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public Color getMouseOverColor() {\r
+        checkWidget();\r
+        return this.mouseOverColor;\r
+    }\r
+\r
+    /**\r
+     * Returns a value which describes the color when the button is selected\r
+     * \r
+     * @return the color when the button is selected\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public Color getSelectedColor() {\r
+        checkWidget();\r
+        return this.selectedColor;\r
+    }\r
+\r
+    /**\r
+     * Returns a value which describes the color of the text when the button is\r
+     * selected\r
+     * \r
+     * @return the color of the text when the button is selected\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+\r
+    public Color getSelectedTextColor() {\r
+        return this.selectedTextColor;\r
+    }\r
+\r
+    /**\r
+     * Returns <code>true</code> if the receiver is selected, and false\r
+     * otherwise.\r
+     * <p>\r
+     * \r
+     * @return the selection state\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not\r
+     *                called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public boolean getSelection() {\r
+        checkWidget();\r
+        return this.selection;\r
+    }\r
+\r
+    /**\r
+     * Returns the receiver's text.\r
+     * \r
+     * @return the receiver's text\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public String getText() {\r
+        checkWidget();\r
+        return this.text;\r
+    }\r
+\r
+    /**\r
+     * Removes the listener from the collection of listeners who will be\r
+     * notified when the control is selected by the user.\r
+     * \r
+     * @param listener the listener which should no longer be notified\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     * @see SelectionListener\r
+     * @see #addSelectionListener\r
+     */\r
+    public void removeSelectionListener(final SelectionListener listener) {\r
+        checkWidget();\r
+        this.listeners.remove(listener);\r
+    }\r
+\r
+    /**\r
+     * Controls how text, images and arrows will be displayed in the receiver.\r
+     * The argument should be one of <code>LEFT</code>, <code>RIGHT</code> or\r
+     * <code>CENTER</code>.\r
+     * \r
+     * @param alignment the new alignment\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setAlignment(final int alignment) {\r
+        checkWidget();\r
+        if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) {\r
+            return;\r
+        }\r
+        this.alignment = alignment;\r
+        redraw();\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's background color to the color specified by the\r
+     * argument.\r
+     * \r
+     * @param color the new color\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument has been\r
+     *                disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setBackgroundColor(final Color backgroundColor) {\r
+        checkWidget();\r
+        this.backgroundColor = backgroundColor;\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's image to the argument, which may be <code>null</code>\r
+     * indicating that no image should be displayed.\r
+     * <p>\r
+     * Note that a Button can display an image and text simultaneously on\r
+     * Windows (starting with XP), GTK+ and OSX. On other platforms, a Button\r
+     * that has an image and text set into it will display the image or text\r
+     * that was set most recently.\r
+     * </p>\r
+     * \r
+     * @param image the image to display on the receiver (may be\r
+     *            <code>null</code>)\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+     *                disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setImage(final Image image) {\r
+        checkWidget();\r
+        this.image = image;\r
+        redraw();\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's color when the mouse if over the button.\r
+     * \r
+     * @param color the new color\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument has been\r
+     *                disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setMouseOverColor(final Color mouseOverColor) {\r
+        checkWidget();\r
+        this.mouseOverColor = mouseOverColor;\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's color when the button is selected.\r
+     * \r
+     * @param color the new color\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument has been\r
+     *                disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setSelectedColor(final Color selectedColor) {\r
+        checkWidget();\r
+        this.selectedColor = selectedColor;\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's text color when the button is selected.\r
+     * \r
+     * @param color the new color\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument has been\r
+     *                disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setSelectedTextColor(final Color selectedTextColor) {\r
+        this.selectedTextColor = selectedTextColor;\r
+    }\r
+\r
+    /**\r
+     * Sets the selection state of the receiver.\r
+     * \r
+     * @param selected the new selection state\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setSelection(final boolean selected) {\r
+        checkWidget();\r
+        this.selection = selected;\r
+        redraw();\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's text.\r
+     * \r
+     * \r
+     * @param string the new text\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_NULL_ARGUMENT - if the text is null</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+     *                disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+     *                thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setText(final String text) {\r
+        checkWidget();\r
+        this.text = text;\r
+        redraw();\r
+    }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/gradientComposite/GradientComposite.java b/org.tizen.common.externals/src/org/mihalis/opal/gradientComposite/GradientComposite.java
new file mode 100644 (file)
index 0000000..80e5c67
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.gradientComposite;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are controls which background's texture is a gradient\r
+ * composite\r
+ */\r
+public class GradientComposite extends Composite {\r
+       private Image oldImage;\r
+       private Color gradientEnd;\r
+       private Color gradientStart;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a widget which will be the parent of the new instance\r
+        *            (cannot be null)\r
+        * @param style the style of widget to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        * @see Composite#Composite(Composite, int)\r
+        * @see SWT#NO_BACKGROUND\r
+        * @see SWT#NO_FOCUS\r
+        * @see SWT#NO_MERGE_PAINTS\r
+        * @see SWT#NO_REDRAW_RESIZE\r
+        * @see SWT#NO_RADIO_GROUP\r
+        * @see SWT#EMBEDDED\r
+        * @see SWT#DOUBLE_BUFFERED\r
+        * @see Widget#getStyle\r
+        */\r
+       public GradientComposite(final Composite parent, final int style) {\r
+               super(parent, style);\r
+               this.addListener(SWT.Resize, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               GradientComposite.this.redrawComposite();\r
+                       }\r
+               });\r
+\r
+               parent.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(GradientComposite.this.oldImage);\r
+                               SWTGraphicUtil.dispose(GradientComposite.this.gradientEnd);\r
+                               SWTGraphicUtil.dispose(GradientComposite.this.gradientStart);\r
+                       }\r
+\r
+               });\r
+\r
+               this.gradientEnd = new Color(this.getDisplay(), 110, 110, 110);\r
+               this.gradientStart = new Color(this.getDisplay(), 0, 0, 0);\r
+\r
+       }\r
+\r
+       /**\r
+        * Redraws the composite\r
+        */\r
+       private void redrawComposite() {\r
+               final Display display = this.getDisplay();\r
+               final Rectangle rect = this.getClientArea();\r
+               final Image newImage = new Image(display, Math.max(1, rect.width), Math.max(1, rect.height));\r
+\r
+               final GC gc = new GC(newImage);\r
+               gc.setForeground(this.gradientStart);\r
+               gc.setBackground(this.gradientEnd);\r
+\r
+               gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height / 2, true);\r
+\r
+               gc.setForeground(this.gradientEnd);\r
+               gc.setBackground(this.gradientStart);\r
+\r
+               gc.fillGradientRectangle(rect.x, rect.height / 2, rect.width, rect.height / 2, true);\r
+               gc.dispose();\r
+\r
+               this.setBackgroundImage(newImage);\r
+               if (this.oldImage != null) {\r
+                       this.oldImage.dispose();\r
+               }\r
+               this.oldImage = newImage;\r
+\r
+       }\r
+\r
+       // ------------------------------------ Getters and Setters\r
+       /**\r
+        * @return the gradientEnd color\r
+        */\r
+       public Color getGradientEnd() {\r
+               return this.gradientEnd;\r
+       }\r
+\r
+       /**\r
+        * @param gradientEnd the gradientEnd color to set\r
+        */\r
+       public void setGradientEnd(final Color gradientEnd) {\r
+               SWTGraphicUtil.dispose(this.gradientEnd);\r
+               this.gradientEnd = gradientEnd;\r
+       }\r
+\r
+       /**\r
+        * @return the gradientStart color\r
+        */\r
+       public Color getGradientStart() {\r
+               return this.gradientStart;\r
+       }\r
+\r
+       /**\r
+        * @param gradientStart the gradientStart color to set\r
+        */\r
+       public void setGradientStart(final Color gradientStart) {\r
+               SWTGraphicUtil.dispose(this.gradientStart);\r
+               this.gradientStart = gradientStart;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/header/Header.java b/org.tizen.common.externals/src/org/mihalis/opal/header/Header.java
new file mode 100644 (file)
index 0000000..6cdd423
--- /dev/null
@@ -0,0 +1,529 @@
+package org.mihalis.opal.header;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Layout;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class provide a header, which is composed of a text, a\r
+ * description and an image.\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>BORDER</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * </dl>\r
+ */\r
+public class Header extends Composite {\r
+\r
+       private Image image;\r
+       private String title;\r
+       private String description;\r
+       private Font titleFont;\r
+       private Color titleColor;\r
+\r
+       private Image oldImage;\r
+       private Color gradientEnd;\r
+       private Color gradientStart;\r
+       private Color separatorColor;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       public Header(final Composite parent, final int style) {\r
+               super(parent, style);\r
+\r
+               final FontData[] fontData = getFont().getFontData();\r
+               if (fontData != null && fontData.length > 0) {\r
+                       final FontData fd = fontData[0];\r
+                       fd.setStyle(SWT.BOLD);\r
+                       fd.setHeight(fd.getHeight() + 2);\r
+                       this.titleFont = new Font(getDisplay(), fd);\r
+               } else {\r
+                       this.titleFont = null;\r
+               }\r
+\r
+               this.titleColor = new Color(getDisplay(), 0, 88, 150);\r
+\r
+               this.gradientEnd = new Color(this.getDisplay(), 239, 239, 239);\r
+               this.gradientStart = new Color(this.getDisplay(), 255, 255, 255);\r
+               this.separatorColor = new Color(this.getDisplay(), 229, 229, 229);\r
+\r
+               this.addListener(SWT.Resize, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               redrawComposite();\r
+                       }\r
+               });\r
+\r
+               this.addListener(SWT.Dispose, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               SWTGraphicUtil.dispose(Header.this.titleColor);\r
+                               SWTGraphicUtil.dispose(Header.this.titleFont);\r
+                               SWTGraphicUtil.dispose(Header.this.oldImage);\r
+                               SWTGraphicUtil.dispose(Header.this.gradientEnd);\r
+                               SWTGraphicUtil.dispose(Header.this.gradientStart);\r
+                               SWTGraphicUtil.dispose(Header.this.separatorColor);\r
+                       }\r
+               });\r
+               setBackgroundMode(SWT.INHERIT_FORCE);\r
+       }\r
+\r
+       /**\r
+        * Redraw the composite\r
+        */\r
+       private void redrawComposite() {\r
+               // Dispose previous content\r
+               for (final Control c : this.getChildren()) {\r
+                       c.dispose();\r
+               }\r
+\r
+               int numberOfColumns = 1;\r
+               if (this.image != null) {\r
+                       numberOfColumns++;\r
+               }\r
+\r
+               super.setLayout(new GridLayout(numberOfColumns, false));\r
+               createContent();\r
+               drawBackground();\r
+       }\r
+\r
+       /**\r
+        * Create the content (title, image, description)\r
+        */\r
+       private void createContent() {\r
+               if (this.title != null) {\r
+                       createTitle();\r
+               }\r
+\r
+               if (this.image != null) {\r
+                       createImage();\r
+               }\r
+\r
+               if (this.description != null) {\r
+                       createDescription();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Create the title\r
+        */\r
+       private void createTitle() {\r
+               final Label labelTitle = new Label(this, SWT.NONE);\r
+               labelTitle.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));\r
+               labelTitle.setFont(this.titleFont);\r
+               labelTitle.setForeground(this.titleColor);\r
+               labelTitle.setText(this.title);\r
+       }\r
+\r
+       /**\r
+        * Create the image\r
+        */\r
+       private void createImage() {\r
+\r
+               int numberOfLines = 1;\r
+\r
+               if (this.title != null && this.description != null) {\r
+                       numberOfLines++;\r
+               }\r
+               final Label labelImage = new Label(this, SWT.NONE);\r
+               labelImage.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, true, 1, numberOfLines));\r
+               labelImage.setImage(this.image);\r
+       }\r
+\r
+       /**\r
+        * Create the description\r
+        */\r
+       private void createDescription() {\r
+               final StyledText labelDescription = new StyledText(this, SWT.WRAP | SWT.READ_ONLY);\r
+               labelDescription.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));\r
+               labelDescription.setEnabled(false);\r
+               labelDescription.setFont(getFont());\r
+               labelDescription.setForeground(getForeground());\r
+               labelDescription.setText("<html><body>" + this.description + "</body></html>");\r
+               SWTGraphicUtil.applyHTMLFormating(labelDescription);\r
+       }\r
+\r
+       /**\r
+        * Draw the background (a gradient+a separator)\r
+        */\r
+       private void drawBackground() {\r
+               final Display display = this.getDisplay();\r
+               final Rectangle rect = this.getClientArea();\r
+               final Image newImage = new Image(display, Math.max(1, rect.width), Math.max(1, rect.height));\r
+\r
+               final GC gc = new GC(newImage);\r
+               gc.setForeground(this.gradientStart);\r
+               gc.setBackground(this.gradientEnd);\r
+\r
+               gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, false);\r
+\r
+               gc.setForeground(this.separatorColor);\r
+               gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height - 1);\r
+\r
+               gc.dispose();\r
+\r
+               this.setBackgroundImage(newImage);\r
+               if (this.oldImage != null) {\r
+                       this.oldImage.dispose();\r
+               }\r
+               this.oldImage = newImage;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#setLayout(org.eclipse.swt.widgets.Layout)\r
+        */\r
+       @Override\r
+       public void setLayout(final Layout layout) {\r
+               throw new UnsupportedOperationException("Not supported");\r
+       }\r
+\r
+       // ------------------------------------ Getters and Setters\r
+\r
+       /**\r
+        * Returns the receiver's description if it has one, or null if it does not.\r
+        * \r
+        * @return the receiver's description if it has one, or null if it does not\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public String getDescription() {\r
+               checkWidget();\r
+               return this.description;\r
+       }\r
+\r
+       /**\r
+        * Returns the receiver's gradient end color.\r
+        * \r
+        * @return the receiver's gradient end color\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getGradientEnd() {\r
+               checkWidget();\r
+               return this.gradientEnd;\r
+       }\r
+\r
+       /**\r
+        * Returns the receiver's gradient start color.\r
+        * \r
+        * @return the receiver's gradient start color\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getGradientStart() {\r
+               checkWidget();\r
+               return this.gradientStart;\r
+       }\r
+\r
+       /**\r
+        * Returns the receiver's image if it has one, or null if it does not.\r
+        * \r
+        * @return the receiver's image if it has one, or null if it does not\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Image getImage() {\r
+               checkWidget();\r
+               return this.image;\r
+       }\r
+\r
+       /**\r
+        * Returns the receiver's separator color.\r
+        * \r
+        * @return the receiver's separator color\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getSeparatorColor() {\r
+               checkWidget();\r
+               return this.separatorColor;\r
+       }\r
+\r
+       /**\r
+        * Returns the receiver's title if it has one, or null if it does not.\r
+        * \r
+        * @return the receiver's title if it has one, or null if it does not\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public String getTitle() {\r
+               checkWidget();\r
+               return this.title;\r
+       }\r
+\r
+       /**\r
+        * Returns the title's color.\r
+        * \r
+        * @return the title's color\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getTitleColor() {\r
+               checkWidget();\r
+               return this.titleColor;\r
+       }\r
+\r
+       /**\r
+        * Returns the title's font.\r
+        * \r
+        * @return the title's font.\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Font getTitleFont() {\r
+               checkWidget();\r
+               return this.titleFont;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's description to the argument, which may be null\r
+        * indicating that no description should be displayed.\r
+        * \r
+        * @param description the description of the header (may be null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setDescription(final String description) {\r
+               checkWidget();\r
+               this.description = description;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's gradient end color.\r
+        * \r
+        * @param gradientEnd the receiver's gradient end color\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setGradientEnd(final Color gradientEnd) {\r
+               checkWidget();\r
+               this.gradientEnd = gradientEnd;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's gradient start color.\r
+        * \r
+        * @param gradientStart the receiver's gradient start color\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setGradientStart(final Color gradientStart) {\r
+               checkWidget();\r
+               this.gradientStart = gradientStart;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's image to the argument, which may be null indicating\r
+        * that no image should be displayed.\r
+        * \r
+        * @param image the image to display on the receiver (may be null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setImage(final Image image) {\r
+               checkWidget();\r
+               this.image = image;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's separator color.\r
+        * \r
+        * @param separatorColor the receiver's separator color\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setSeparatorColor(final Color separatorColor) {\r
+               this.separatorColor = separatorColor;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's title to the argument, which may be null indicating\r
+        * that no title should be displayed.\r
+        * \r
+        * @param title the title\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setTitle(final String title) {\r
+               checkWidget();\r
+               this.title = title;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's title color.\r
+        * \r
+        * @param headerColor the receiver's title color\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setTitleColor(final Color headerColor) {\r
+               checkWidget();\r
+               this.titleColor = headerColor;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's title font.\r
+        * \r
+        * @param headerFont the receiver's title font\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setTitleFont(final Font headerFont) {\r
+               checkWidget();\r
+               this.titleFont = headerFont;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/heapManager/HeapManager.java b/org.tizen.common.externals/src/org/mihalis/opal/heapManager/HeapManager.java
new file mode 100644 (file)
index 0000000..a702b6f
--- /dev/null
@@ -0,0 +1,297 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.heapManager;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are controls that display the memory used, the whole\r
+ * memory, and contains a button to perform a GC\r
+ */\r
+public class HeapManager extends Composite {\r
+       private Canvas bar;\r
+       private Button button;\r
+       private int heapMaxSize;\r
+       private int heapSize;\r
+       private Color barBorderColor;\r
+       private Color barInnerColor;\r
+       private Color barTextColor;\r
+       private Color barGradientColorTopStart;\r
+       private Color barGradientColorTopEnd;\r
+       private Color barGradientColorMiddleStart;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a widget which will be the parent of the new instance\r
+        *            (cannot be null)\r
+        * @param style the style of widget to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        * @see Composite#Composite(Composite, int)\r
+        * @see Widget#getStyle\r
+        */\r
+       public HeapManager(final Composite parent, final int style) {\r
+               super(parent, style);\r
+               final GridLayout gridLayout = new GridLayout(2, false);\r
+               gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;\r
+               setLayout(gridLayout);\r
+\r
+               createBar();\r
+               createButton();\r
+               updateContent();\r
+               createDefaultColors();\r
+\r
+               addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(HeapManager.this.barBorderColor);\r
+                               SWTGraphicUtil.dispose(HeapManager.this.barInnerColor);\r
+                               SWTGraphicUtil.dispose(HeapManager.this.barGradientColorTopStart);\r
+                               SWTGraphicUtil.dispose(HeapManager.this.barGradientColorTopEnd);\r
+                               SWTGraphicUtil.dispose(HeapManager.this.barGradientColorMiddleStart);\r
+                               SWTGraphicUtil.dispose(HeapManager.this.barTextColor);\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Creates the bar that displays the memory\r
+        */\r
+       private void createBar() {\r
+               this.bar = new Canvas(this, SWT.NONE);\r
+               final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false);\r
+               gd.minimumWidth = 100;\r
+               gd.heightHint = 30;\r
+               this.bar.setLayoutData(gd);\r
+               this.heapMaxSize = (int) (Runtime.getRuntime().maxMemory() / (1024 * 1024));\r
+               this.bar.addPaintListener(new PaintListener() {\r
+\r
+                       @Override\r
+                       public void paintControl(final PaintEvent e) {\r
+                               drawBar(e);\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Draw the bar\r
+        * \r
+        * @param e {@link PaintEvent}\r
+        */\r
+       private void drawBar(final PaintEvent e) {\r
+               final GC gc = e.gc;\r
+               final Rectangle clientArea = this.bar.getClientArea();\r
+\r
+               gc.setForeground(this.barBorderColor);\r
+               gc.setBackground(this.barInnerColor);\r
+               gc.fillRectangle(clientArea);\r
+               gc.drawRectangle(clientArea.x, clientArea.y, clientArea.width - 1, clientArea.height - 1);\r
+\r
+               final float width = (clientArea.width - 2f) * this.heapSize / this.heapMaxSize;\r
+\r
+               gc.setForeground(this.barGradientColorTopStart);\r
+               gc.setBackground(this.barGradientColorTopEnd);\r
+               gc.fillGradientRectangle(clientArea.x + 1, clientArea.y + 1, (int) width, clientArea.height / 2, true);\r
+\r
+               gc.setForeground(this.barGradientColorMiddleStart);\r
+               gc.setBackground(this.barBorderColor);\r
+               gc.fillGradientRectangle(clientArea.x + 1, clientArea.height / 2, (int) width, clientArea.height / 2, true);\r
+\r
+               final String message = this.heapSize + " " + ResourceManager.getLabel(ResourceManager.MEGABYTES) + "/" + //\r
+                               this.heapMaxSize + " " + ResourceManager.getLabel(ResourceManager.MEGABYTES);\r
+               final Point size = gc.stringExtent(message);\r
+\r
+               gc.setForeground(this.barTextColor);\r
+               gc.setFont(getFont());\r
+               gc.drawText(message, (clientArea.width - size.x) / 2, (clientArea.height - size.y) / 2, true);\r
+\r
+               gc.dispose();\r
+\r
+       }\r
+\r
+       /**\r
+        * Create the button used to perform GC\r
+        */\r
+       private void createButton() {\r
+               this.button = new Button(this, SWT.PUSH);\r
+               this.button.setImage(SWTGraphicUtil.createImage("images/trash.png"));\r
+               this.button.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false));\r
+               this.button.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               System.gc();\r
+                       }\r
+\r
+               });\r
+               this.button.setToolTipText(ResourceManager.getLabel(ResourceManager.PERFORM_GC));\r
+               this.button.pack();\r
+       }\r
+\r
+       /**\r
+        * Update the content of the bar\r
+        */\r
+       private void updateContent() {\r
+               getDisplay().timerExec(500, new Runnable() {\r
+\r
+                       @Override\r
+                       public void run() {\r
+                               HeapManager.this.heapSize = (int) (Runtime.getRuntime().totalMemory() / (1024 * 1024));\r
+                               if (!isDisposed()) {\r
+                                       HeapManager.this.bar.redraw();\r
+                                       if (!getDisplay().isDisposed()) {\r
+                                               getDisplay().timerExec(500, this);\r
+                                       }\r
+                               }\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Creates the default colors\r
+        */\r
+       private void createDefaultColors() {\r
+               this.barTextColor = new Color(getDisplay(), 57, 98, 149);\r
+               this.barInnerColor = new Color(getDisplay(), 219, 230, 243);\r
+               this.barBorderColor = new Color(getDisplay(), 101, 148, 207);\r
+               this.barGradientColorTopStart = new Color(getDisplay(), 175, 202, 237);\r
+               this.barGradientColorTopEnd = new Color(getDisplay(), 136, 177, 229);\r
+               this.barGradientColorMiddleStart = new Color(getDisplay(), 112, 161, 223);\r
+\r
+       }\r
+\r
+       /**\r
+        * @return the barBorderColor\r
+        */\r
+       public Color getBarBorderColor() {\r
+               return this.barBorderColor;\r
+       }\r
+\r
+       /**\r
+        * @param barBorderColor the barBorderColor to set\r
+        */\r
+       public void setBarBorderColor(final Color barBorderColor) {\r
+               this.barBorderColor = barBorderColor;\r
+       }\r
+\r
+       /**\r
+        * @return the barInnerColor\r
+        */\r
+       public Color getBarInnerColor() {\r
+               return this.barInnerColor;\r
+       }\r
+\r
+       /**\r
+        * @param barInnerColor the barInnerColor to set\r
+        */\r
+       public void setBarInnerColor(final Color barInnerColor) {\r
+               this.barInnerColor = barInnerColor;\r
+       }\r
+\r
+       /**\r
+        * @return the barTextColor\r
+        */\r
+       public Color getBarTextColor() {\r
+               return this.barTextColor;\r
+       }\r
+\r
+       /**\r
+        * @param barTextColor the barTextColor to set\r
+        */\r
+       public void setBarTextColor(final Color barTextColor) {\r
+               this.barTextColor = barTextColor;\r
+       }\r
+\r
+       /**\r
+        * @return the barGradientColorTopStart\r
+        */\r
+       public Color getBarGradientColorTopStart() {\r
+               return this.barGradientColorTopStart;\r
+       }\r
+\r
+       /**\r
+        * @param barGradientColorTopStart the barGradientColorTopStart to set\r
+        */\r
+       public void setBarGradientColorTopStart(final Color barGradientColorTopStart) {\r
+               this.barGradientColorTopStart = barGradientColorTopStart;\r
+       }\r
+\r
+       /**\r
+        * @return the barGradientColorTopEnd\r
+        */\r
+       public Color getBarGradientColorTopEnd() {\r
+               return this.barGradientColorTopEnd;\r
+       }\r
+\r
+       /**\r
+        * @param barGradientColorTopEnd the barGradientColorTopEnd to set\r
+        */\r
+       public void setBarGradientColorTopEnd(final Color barGradientColorTopEnd) {\r
+               this.barGradientColorTopEnd = barGradientColorTopEnd;\r
+       }\r
+\r
+       /**\r
+        * @return the barGradientColorMiddleStart\r
+        */\r
+       public Color getBarGradientColorMiddleStart() {\r
+               return this.barGradientColorMiddleStart;\r
+       }\r
+\r
+       /**\r
+        * @param barGradientColorMiddleStart the barGradientColorMiddleStart to set\r
+        */\r
+       public void setBarGradientColorMiddleStart(final Color barGradientColorMiddleStart) {\r
+               this.barGradientColorMiddleStart = barGradientColorMiddleStart;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/horizontalSpinner/HorizontalSpinner.java b/org.tizen.common.externals/src/org/mihalis/opal/horizontalSpinner/HorizontalSpinner.java
new file mode 100644 (file)
index 0000000..5362a36
--- /dev/null
@@ -0,0 +1,947 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.horizontalSpinner;\r
+\r
+import java.text.DecimalFormatSymbols;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.KeyAdapter;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.events.VerifyEvent;\r
+import org.eclipse.swt.events.VerifyListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Cursor;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Menu;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.mihalis.opal.utils.StringUtil;\r
+\r
+/**\r
+ * Instances of this class are selectable user interface objects that allow the user to enter and modify numeric values.\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>READ_ONLY, FLAP</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>Selection, Modify</dd>\r
+ * </dl>\r
+ * </p>\r
+ */\r
+public class HorizontalSpinner extends Composite {\r
+    private final List<ModifyListener> modifyListeners = new ArrayList<ModifyListener>();\r
+    private final List<SelectionListener> selectionListeners = new ArrayList<SelectionListener>();\r
+\r
+    private Button leftButton;\r
+    private Button rightButton;\r
+    private Text text;\r
+    private int digits = 0;\r
+    private int increment = 1;\r
+    private int maximum = 0;\r
+    private int minimum = 255;\r
+    private int pageIncrement = 10;\r
+    private int storedValue = 0;\r
+\r
+    private final char decimalFormatSeparator;\r
+\r
+    /**\r
+     * Constructs a new instance of this class given its parent and a style value describing its behavior and appearance.\r
+     * <p>\r
+     * The style value is either one of the style constants defined in class <code>SWT</code> which is applicable to instances of this class, or must be built by <em>bitwise OR</em>'ing together (that is, using the <code>int</code> "|" operator) two or more of those <code>SWT</code> style constants. The class description lists the style constants that are applicable to the class. Style bits are also inherited from superclasses.\r
+     * </p>\r
+     * \r
+     * @param parent a composite control which will be the parent of the new instance (cannot be null)\r
+     * @param style the style of control to construct\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>\r
+     *                <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>\r
+     *                </ul>\r
+     * \r
+     * @see SWT#READ_ONLY\r
+     * @see SWT#FLAT\r
+     */\r
+    public HorizontalSpinner(final Composite parent, final int style) {\r
+        super(parent, style);\r
+\r
+        final GridLayout gd = new GridLayout(3, false);\r
+        gd.horizontalSpacing = gd.verticalSpacing = 0;\r
+        gd.marginWidth = gd.marginHeight = 0;\r
+        this.setLayout(gd);\r
+\r
+        this.createContent(style);\r
+        this.addTextListeners();\r
+        this.addButtonsListener();\r
+        this.addModifyListeners();\r
+\r
+        this.decimalFormatSeparator = new DecimalFormatSymbols().getDecimalSeparator();\r
+    }\r
+\r
+    /**\r
+     * Create the content of the widget\r
+     * \r
+     * @param style style of the widget\r
+     */\r
+    private void createContent(final int style) {\r
+        final boolean readOnly = (style & SWT.READ_ONLY) == SWT.READ_ONLY;\r
+        final boolean flat = (style & SWT.FLAT) == SWT.FLAT;\r
+\r
+        final int buttonStyle = SWT.ARROW | (flat ? SWT.FLAT : SWT.NONE);\r
+        this.leftButton = new Button(this, buttonStyle | SWT.LEFT);\r
+        this.leftButton.setFont(this.getFont());\r
+        this.leftButton.setBackground(this.getBackground());\r
+        this.leftButton.setCursor(this.getCursor());\r
+        this.leftButton.setEnabled(this.getEnabled());\r
+        this.leftButton.setFont(this.getFont());\r
+        this.leftButton.setForeground(this.getForeground());\r
+        this.leftButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false));\r
+\r
+        this.text = new Text(this, readOnly ? SWT.READ_ONLY : SWT.NONE);\r
+        final GridData gd = new GridData(GridData.FILL, GridData.CENTER, true, false);\r
+        gd.minimumWidth = 40;\r
+        this.text.setLayoutData(gd);\r
+\r
+        this.rightButton = new Button(this, buttonStyle | SWT.RIGHT);\r
+        this.rightButton.setFont(this.getFont());\r
+        this.rightButton.setBackground(this.getBackground());\r
+        this.rightButton.setCursor(this.getCursor());\r
+        this.rightButton.setEnabled(this.getEnabled());\r
+        this.rightButton.setFont(this.getFont());\r
+        this.rightButton.setForeground(this.getForeground());\r
+        this.rightButton.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false));\r
+\r
+    }\r
+\r
+    /**\r
+     * Add the text listeners\r
+     */\r
+    private void addTextListeners() {\r
+        this.text.addVerifyListener(new VerifyListener() {\r
+\r
+            @Override\r
+            public void verifyText(final VerifyEvent e) {\r
+                if (e.character != 0 && !Character.isDigit(e.character) && e.keyCode != SWT.BS && e.keyCode != SWT.DEL) {\r
+                    e.doit = false;\r
+                    return;\r
+                }\r
+\r
+                e.doit = HorizontalSpinner.this.verifyEntryAndStoreValue(e.text, e.keyCode);\r
+\r
+            }\r
+        });\r
+\r
+        this.text.addKeyListener(new KeyAdapter() {\r
+\r
+            /**\r
+             * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent)\r
+             */\r
+            @Override\r
+            public void keyReleased(final KeyEvent e) {\r
+                if (e.keyCode == SWT.ARROW_UP) {\r
+                    HorizontalSpinner.this.increaseValue(HorizontalSpinner.this.increment);\r
+                }\r
+                if (e.keyCode == SWT.ARROW_DOWN) {\r
+                    HorizontalSpinner.this.decreaseValue(HorizontalSpinner.this.increment);\r
+                }\r
+                if (e.keyCode == SWT.PAGE_UP) {\r
+                    HorizontalSpinner.this.increaseValue(HorizontalSpinner.this.pageIncrement);\r
+                }\r
+                if (e.keyCode == SWT.PAGE_DOWN) {\r
+                    HorizontalSpinner.this.decreaseValue(HorizontalSpinner.this.pageIncrement);\r
+                }\r
+            }\r
+\r
+        });\r
+\r
+        this.text.addFocusListener(new org.eclipse.swt.events.FocusAdapter() {\r
+\r
+            /**\r
+             * @see org.eclipse.swt.events.FocusAdapter#focusLost(org.eclipse.swt.events.FocusEvent)\r
+             */\r
+            @Override\r
+            public void focusLost(final org.eclipse.swt.events.FocusEvent e) {\r
+                if (HorizontalSpinner.this.text.getText().trim().equals("")) {\r
+                    HorizontalSpinner.this.setSelection(HorizontalSpinner.this.storedValue);\r
+                }\r
+            }\r
+\r
+        });\r
+\r
+    }\r
+\r
+    /**\r
+     * Verify the entry and store the value in the field storedValue\r
+     * \r
+     * @param entry entry to check\r
+     * @param keyCode code of the typed key\r
+     * @return <code>true</code> if the entry if correct, <code>false</code> otherwise\r
+     */\r
+    private boolean verifyEntryAndStoreValue(final String entry, final int keyCode) {\r
+        final String work;\r
+        if (keyCode == SWT.DEL) {\r
+            work = StringUtil.removeCharAt(this.text.getText(), this.text.getCaretPosition());\r
+        } else if (keyCode == SWT.BS && this.text.getCaretPosition() == 0) {\r
+            work = StringUtil.removeCharAt(this.text.getText(), this.text.getCaretPosition() - 1);\r
+        } else if (keyCode == 0) {\r
+            work = entry;\r
+        } else {\r
+            work = StringUtil.insertString(this.text.getText(), entry, this.text.getCaretPosition());\r
+        }\r
+\r
+        try {\r
+            final double d = Double.parseDouble(work.replace(this.decimalFormatSeparator, '.'));\r
+            this.storedValue = (int) (d * Math.pow(10, this.getDigits()));\r
+        } catch (final NumberFormatException nfe) {\r
+            return false;\r
+        }\r
+\r
+        for (final SelectionListener s : HorizontalSpinner.this.selectionListeners) {\r
+            s.widgetSelected(null);\r
+        }\r
+\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Add the listener to the buttons\r
+     */\r
+    private void addButtonsListener() {\r
+        this.leftButton.addSelectionListener(new SelectionAdapter() {\r
+\r
+            /**\r
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+             */\r
+            @Override\r
+            public void widgetSelected(final SelectionEvent e) {\r
+                HorizontalSpinner.this.decreaseValue(HorizontalSpinner.this.increment);\r
+            }\r
+        });\r
+\r
+        this.rightButton.addSelectionListener(new SelectionAdapter() {\r
+\r
+            /**\r
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+             */\r
+            @Override\r
+            public void widgetSelected(final SelectionEvent e) {\r
+                HorizontalSpinner.this.increaseValue(HorizontalSpinner.this.increment);\r
+            }\r
+        });\r
+\r
+    }\r
+\r
+    /**\r
+     * Increase the value stored in this snippet\r
+     * \r
+     * @param value value to increase\r
+     */\r
+    private void increaseValue(final int value) {\r
+        this.setSelection(this.getSelection() + value);\r
+\r
+    }\r
+\r
+    /**\r
+     * Decrease the value stored in this snippet\r
+     * \r
+     * @param value value to decrease\r
+     */\r
+    private void decreaseValue(final int value) {\r
+        this.setSelection(this.getSelection() - value);\r
+    }\r
+\r
+    /**\r
+     * Add the modify listeners\r
+     */\r
+    private void addModifyListeners() {\r
+        this.text.addModifyListener(new ModifyListener() {\r
+\r
+            @Override\r
+            public void modifyText(final ModifyEvent e) {\r
+                for (final ModifyListener m : HorizontalSpinner.this.modifyListeners) {\r
+                    m.modifyText(e);\r
+                }\r
+\r
+            }\r
+        });\r
+\r
+    }\r
+\r
+    /**\r
+     * Adds the listener to the collection of listeners who will be notified when the receiver's text is modified, by sending it one of the messages defined in the <code>ModifyListener</code> interface.\r
+     * \r
+     * @param listener the listener which should be notified\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     * @see ModifyListener\r
+     * @see #removeModifyListener\r
+     * @see org.eclipse.swt.widgets.Spinner#addModifyListener(org.eclipse.swt.events.ModifyListener)\r
+     */\r
+\r
+    public void addModifyListener(final ModifyListener listener) {\r
+        this.checkWidget();\r
+        this.modifyListeners.add(listener);\r
+    }\r
+\r
+    /**\r
+     * Adds the listener to the collection of listeners who will be notified when the control is selected by the user, by sending it one of the messages defined in the <code>SelectionListener</code> interface.\r
+     * <p>\r
+     * <code>widgetSelected</code> is not called for texts. <code>widgetDefaultSelected</code> is typically called when ENTER is pressed in a single-line text.\r
+     * </p>\r
+     * \r
+     * @param listener the listener which should be notified when the control is selected by the user\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     * @see SelectionListener\r
+     * @see #removeSelectionListener\r
+     * @see SelectionEvent\r
+     */\r
+    public void addSelectionListener(final SelectionListener listener) {\r
+        this.checkWidget();\r
+        this.selectionListeners.add(listener);\r
+    }\r
+\r
+    /**\r
+     * Copies the selected text.\r
+     * <p>\r
+     * The current selection is copied to the clipboard.\r
+     * </p>\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void copy() {\r
+        this.checkWidget();\r
+        this.text.copy();\r
+    }\r
+\r
+    /**\r
+     * Cuts the selected text.\r
+     * <p>\r
+     * The current selection is first copied to the clipboard and then deleted from the widget.\r
+     * </p>\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void cut() {\r
+        this.checkWidget();\r
+        this.text.cut();\r
+    }\r
+\r
+    /**\r
+     * Returns the number of decimal places used by the receiver.\r
+     * \r
+     * @return the digits\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public int getDigits() {\r
+        this.checkWidget();\r
+        return this.digits;\r
+    }\r
+\r
+    /**\r
+     * Returns the amount that the receiver's value will be modified by when the up/down arrows are pressed.\r
+     * \r
+     * @return the increment\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public int getIncrement() {\r
+        this.checkWidget();\r
+        return this.increment;\r
+    }\r
+\r
+    /**\r
+     * Returns the maximum value which the receiver will allow.\r
+     * \r
+     * @return the maximum\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public int getMaximum() {\r
+        this.checkWidget();\r
+        return this.maximum;\r
+    }\r
+\r
+    /**\r
+     * Returns the minimum value which the receiver will allow.\r
+     * \r
+     * @return the minimum\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public int getMinimum() {\r
+        this.checkWidget();\r
+        return this.minimum;\r
+    }\r
+\r
+    /**\r
+     * Returns the amount that the receiver's position will be modified by when the page up/down keys are pressed.\r
+     * \r
+     * @return the page increment\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public int getPageIncrement() {\r
+        this.checkWidget();\r
+        return this.pageIncrement;\r
+    }\r
+\r
+    /**\r
+     * Returns the <em>selection</em>, which is the receiver's position.\r
+     * \r
+     * @return the selection\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public int getSelection() {\r
+        this.checkWidget();\r
+        return this.storedValue;\r
+\r
+    }\r
+\r
+    /**\r
+     * Returns a string containing a copy of the contents of the receiver's text field, or an empty string if there are no contents.\r
+     * \r
+     * @return the receiver's text\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     */\r
+    public String getText() {\r
+        this.checkWidget();\r
+        return this.text.getText();\r
+    }\r
+\r
+    /**\r
+     * Returns the maximum number of characters that the receiver's text field is capable of holding. If this has not been changed by <code>setTextLimit()</code>, it will be the constant <code>Spinner.LIMIT</code>.\r
+     * \r
+     * @return the text limit\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     * @see #LIMIT\r
+     */\r
+    public int getTextLimit() {\r
+        this.checkWidget();\r
+        return this.text.getTextLimit();\r
+    }\r
+\r
+    /**\r
+     * Pastes text from clipboard.\r
+     * <p>\r
+     * The selected text is deleted from the widget and new text inserted from the clipboard.\r
+     * </p>\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void paste() {\r
+        this.checkWidget();\r
+        this.text.paste();\r
+    }\r
+\r
+    /**\r
+     * Removes the listener from the collection of listeners who will be notified when the receiver's text is modified.\r
+     * \r
+     * @param listener the listener which should no longer be notified\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     * @see ModifyListener\r
+     * @see #addModifyListener\r
+     */\r
+    public void removeModifyListener(final ModifyListener listener) {\r
+        this.checkWidget();\r
+        this.modifyListeners.remove(listener);\r
+    }\r
+\r
+    /**\r
+     * Removes the listener from the collection of listeners who will be notified when the control is selected by the user.\r
+     * \r
+     * @param listener the listener which should no longer be notified\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     * @see SelectionListener\r
+     * @see #addSelectionListener\r
+     */\r
+    public void removeSelectionListener(final SelectionListener listener) {\r
+        this.checkWidget();\r
+        this.selectionListeners.remove(listener);\r
+    }\r
+\r
+    /**\r
+     * Sets the number of decimal places used by the receiver.\r
+     * <p>\r
+     * The digit setting is used to allow for floating point values in the receiver. For example, to set the selection to a floating point value of 1.37 call setDigits() with a value of 2 and setSelection() with a value of 137. Similarly, if getDigits() has a value of 2 and getSelection() returns 137 this should be interpreted as 1.37. This applies to all numeric APIs.\r
+     * </p>\r
+     * \r
+     * @param value the new digits (must be greater than or equal to zero)\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the value is less than zero</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setDigits(final int value) {\r
+        this.checkWidget();\r
+        this.digits = value;\r
+        this.convertSelection();\r
+    }\r
+\r
+    /**\r
+     * Sets the amount that the receiver's value will be modified by when the up/down arrows are pressed to the argument, which must be at least one.\r
+     * \r
+     * @param value the new increment (must be greater than zero)\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setIncrement(final int value) {\r
+        this.checkWidget();\r
+        this.increment = value;\r
+    }\r
+\r
+    /**\r
+     * Sets the maximum value that the receiver will allow. This new value will be ignored if it is less than the receiver's current minimum value. If the new maximum is applied then the receiver's selection value will be adjusted if necessary to fall within its new range.\r
+     * \r
+     * @param value the new maximum, which must be greater than or equal to the current minimum\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setMaximum(final int value) {\r
+        this.checkWidget();\r
+        this.maximum = value;\r
+    }\r
+\r
+    /**\r
+     * Sets the minimum value that the receiver will allow. This new value will be ignored if it is greater than the receiver's current maximum value. If the new minimum is applied then the receiver's selection value will be adjusted if necessary to fall within its new range.\r
+     * \r
+     * @param value the new minimum, which must be less than or equal to the current maximum\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setMinimum(final int value) {\r
+        this.checkWidget();\r
+        this.minimum = value;\r
+    }\r
+\r
+    /**\r
+     * Sets the amount that the receiver's position will be modified by when the page up/down keys are pressed to the argument, which must be at least one.\r
+     * \r
+     * @param value the page increment (must be greater than zero)\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setPageIncrement(final int value) {\r
+        this.checkWidget();\r
+        this.pageIncrement = value;\r
+    }\r
+\r
+    /**\r
+     * Sets the <em>selection</em>, which is the receiver's position, to the argument. If the argument is not within the range specified by minimum and maximum, it will be adjusted to fall within this range.\r
+     * \r
+     * @param value the new selection (must be zero or greater)\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setSelection(int selection) {\r
+        this.checkWidget();\r
+        if (selection < this.minimum) {\r
+            selection = this.minimum;\r
+        } else if (selection > this.maximum) {\r
+            selection = this.maximum;\r
+        }\r
+\r
+        this.storedValue = selection;\r
+        this.text.setText(this.convertSelection());\r
+        this.text.selectAll();\r
+        this.text.setFocus();\r
+\r
+        for (final SelectionListener s : HorizontalSpinner.this.selectionListeners) {\r
+            s.widgetSelected(null);\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Convert the selection into a string\r
+     * \r
+     * @return the string representation of the selection\r
+     */\r
+    private String convertSelection() {\r
+        if (this.getDigits() == 0) {\r
+            return String.valueOf(this.storedValue);\r
+        }\r
+        final String temp = String.valueOf(this.storedValue * Math.pow(10, -1 * this.getDigits()));\r
+        return temp.replace('.', this.decimalFormatSeparator);\r
+    }\r
+\r
+    /**\r
+     * Sets the maximum number of characters that the receiver's text field is capable of holding to be the argument.\r
+     * <p>\r
+     * To reset this value to the default, use <code>setTextLimit(Spinner.LIMIT)</code>. Specifying a limit value larger than <code>Spinner.LIMIT</code> sets the receiver's limit to <code>Spinner.LIMIT</code>.\r
+     * </p>\r
+     * \r
+     * @param limit new text limit\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     * @see #LIMIT\r
+     */\r
+    public void setTextLimit(final int limit) {\r
+        this.checkWidget();\r
+        this.text.setTextLimit(limit);\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's selection, minimum value, maximum value, digits, increment and page increment all at once.\r
+     * <p>\r
+     * Note: This is similar to setting the values individually using the appropriate methods, but may be implemented in a more efficient fashion on some platforms.\r
+     * </p>\r
+     * \r
+     * @param selection the new selection value\r
+     * @param minimum the new minimum value\r
+     * @param maximum the new maximum value\r
+     * @param digits the new digits value\r
+     * @param increment the new increment value\r
+     * @param pageIncrement the new pageIncrement value\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    public void setValues(final int selection, final int minimum, final int maximum, final int digits, final int increment, final int pageIncrement) {\r
+        this.setMinimum(minimum);\r
+        this.setMaximum(maximum);\r
+        this.setDigits(digits);\r
+        this.setIncrement(increment);\r
+        this.setPageIncrement(pageIncrement);\r
+        this.setSelection(selection);\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's drag detect state. If the argument is <code>true</code>, the receiver will detect drag gestures, otherwise these gestures will be ignored.\r
+     * \r
+     * @param dragDetect the new drag detect state\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    @Override\r
+    public boolean setFocus() {\r
+        this.checkWidget();\r
+        return this.text.setFocus();\r
+    }\r
+\r
+    /**\r
+     * Forces the receiver to have the <em>keyboard focus</em>, causing all keyboard events to be delivered to it.\r
+     * \r
+     * @return <code>true</code> if the control got focus, and <code>false</code> if it was unable to.\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     * \r
+     * @see #setFocus\r
+     */\r
+    @Override\r
+    public boolean forceFocus() {\r
+        this.checkWidget();\r
+        return this.text.forceFocus();\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's background color to the color specified by the argument, or to the default system color for the control if the argument is null.\r
+     * <p>\r
+     * Note: This operation is a hint and may be overridden by the platform. For example, on Windows the background of a Button cannot be changed.\r
+     * </p>\r
+     * \r
+     * @param color the new color (or null)\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    @Override\r
+    public void setBackground(final Color color) {\r
+        super.setBackground(color);\r
+        this.leftButton.setBackground(color);\r
+        this.rightButton.setBackground(color);\r
+        this.text.setBackground(color);\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's background image to the image specified by the argument, or to the default system color for the control if the argument is null. The background image is tiled to fill the available space.\r
+     * <p>\r
+     * Note: This operation is a hint and may be overridden by the platform. For example, on Windows the background of a Button cannot be changed.\r
+     * </p>\r
+     * \r
+     * @param image the new image (or null)\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument is not a bitmap</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    @Override\r
+    public void setBackgroundImage(final Image image) {\r
+        super.setBackgroundImage(image);\r
+        this.leftButton.setBackgroundImage(image);\r
+        this.rightButton.setBackgroundImage(image);\r
+        this.text.setBackgroundImage(image);\r
+\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's cursor to the cursor specified by the argument, or to the default cursor for that kind of control if the argument is null.\r
+     * <p>\r
+     * When the mouse pointer passes over a control its appearance is changed to match the control's cursor.\r
+     * </p>\r
+     * \r
+     * @param cursor the new cursor (or null)\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    @Override\r
+    public void setCursor(final Cursor cursor) {\r
+        super.setCursor(cursor);\r
+        this.leftButton.setCursor(cursor);\r
+        this.rightButton.setCursor(cursor);\r
+        this.text.setCursor(cursor);\r
+\r
+    }\r
+\r
+    /**\r
+     * Enables the receiver if the argument is <code>true</code>, and disables it otherwise. A disabled control is typically not selectable from the user interface and draws with an inactive or "grayed" look.\r
+     * \r
+     * @param enabled the new enabled state\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    @Override\r
+    public void setEnabled(final boolean enabled) {\r
+        super.setEnabled(enabled);\r
+        this.leftButton.setEnabled(enabled);\r
+        this.rightButton.setEnabled(enabled);\r
+        this.text.setEnabled(enabled);\r
+\r
+    }\r
+\r
+    /**\r
+     * Sets the font that the receiver will use to paint textual information to the font specified by the argument, or to the default font for that kind of control if the argument is null.\r
+     * \r
+     * @param font the new font (or null)\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    @Override\r
+    public void setFont(final Font font) {\r
+        super.setFont(font);\r
+        this.text.setFont(font);\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's foreground color to the color specified by the argument, or to the default system color for the control if the argument is null.\r
+     * <p>\r
+     * Note: This operation is a hint and may be overridden by the platform.\r
+     * </p>\r
+     * \r
+     * @param color the new color (or null)\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    @Override\r
+    public void setForeground(final Color color) {\r
+        super.setForeground(color);\r
+        this.leftButton.setForeground(color);\r
+        this.rightButton.setForeground(color);\r
+        this.text.setForeground(color);\r
+\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's pop up menu to the argument. All controls may optionally have a pop up menu that is displayed when the user requests one for the control. The sequence of key strokes, button presses and/or button releases that are used to request a pop up menu is platform specific.\r
+     * <p>\r
+     * Note: Disposing of a control that has a pop up menu will dispose of the menu. To avoid this behavior, set the menu to null before the control is disposed.\r
+     * </p>\r
+     * \r
+     * @param menu the new pop up menu\r
+     * \r
+     * @exception IllegalArgumentException <ul>\r
+     *                <li>ERROR_MENU_NOT_POP_UP - the menu is not a pop up menu</li>\r
+     *                <li>ERROR_INVALID_PARENT - if the menu is not in the same widget tree</li>\r
+     *                <li>ERROR_INVALID_ARGUMENT - if the menu has been disposed</li>\r
+     *                </ul>\r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    @Override\r
+    public void setMenu(final Menu menu) {\r
+        super.setMenu(menu);\r
+        this.leftButton.setMenu(menu);\r
+        this.rightButton.setMenu(menu);\r
+        this.text.setMenu(menu);\r
+    }\r
+\r
+    /**\r
+     * Sets the receiver's tool tip text to the argument, which may be null indicating that the default tool tip for the control will be shown. For a control that has a default tool tip, such as the Tree control on Windows, setting the tool tip text to an empty string replaces the default, causing no tool tip text to be shown.\r
+     * <p>\r
+     * The mnemonic indicator (character '&amp;') is not displayed in a tool tip. To display a single '&amp;' in the tool tip, the character '&amp;' can be escaped by doubling it in the string.\r
+     * </p>\r
+     * \r
+     * @param string the new tool tip text (or null)\r
+     * \r
+     * @exception SWTException <ul>\r
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>\r
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>\r
+     *                </ul>\r
+     */\r
+    @Override\r
+    public void setToolTipText(final String tooltipText) {\r
+        super.setToolTipText(tooltipText);\r
+        this.leftButton.setToolTipText(tooltipText);\r
+        this.rightButton.setToolTipText(tooltipText);\r
+        this.text.setToolTipText(tooltipText);\r
+    }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ISItem.java b/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ISItem.java
new file mode 100644 (file)
index 0000000..fc91099
--- /dev/null
@@ -0,0 +1,114 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.imageSelector;\r
+\r
+import org.eclipse.swt.graphics.Point;\r
+import org.mihalis.opal.OpalItem;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class represents items manipulated by the ImageSelector\r
+ * widget\r
+ */\r
+public class ISItem extends OpalItem implements Comparable<ISItem> {\r
+\r
+       private double zPosition;\r
+       private Point upperLeftCorner;\r
+       private Point lowerRightCorner;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param fileName file name of the image that will be displayed\r
+        */\r
+       public ISItem(final String fileName) {\r
+               setImage(SWTGraphicUtil.createImage(fileName));\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param title the title of the image\r
+        * @param fileName file name of the image that will be displayed\r
+        */\r
+       public ISItem(final String title, final String fileName) {\r
+               setImage(SWTGraphicUtil.createImage(fileName));\r
+               setText(title);\r
+       }\r
+\r
+       /**\r
+        * @return the zPosition\r
+        */\r
+       double getzPosition() {\r
+               return this.zPosition;\r
+       }\r
+\r
+       /**\r
+        * @param zPosition the zPosition to set\r
+        */\r
+       ISItem setzPosition(final double zPosition) {\r
+               this.zPosition = zPosition;\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the upperLeftCorner\r
+        */\r
+       Point getUpperLeftCorner() {\r
+               return this.upperLeftCorner;\r
+       }\r
+\r
+       /**\r
+        * @param x the upperLeftCorner.x to set\r
+        * @param y the upperLeftCorner.y to set\r
+        */\r
+       void setUpperLeftCorner(final int x, final int y) {\r
+               this.upperLeftCorner = new Point(x, y);\r
+       }\r
+\r
+       /**\r
+        * @return the lowerRightCorner\r
+        */\r
+       Point getLowerRightCorner() {\r
+               return this.lowerRightCorner;\r
+       }\r
+\r
+       /**\r
+        * @param x the lowerRightCorner.x to set\r
+        * @param y the lowerRightCorner.y to set\r
+        */\r
+       void setLowerRightCorner(final int x, final int y) {\r
+               this.lowerRightCorner = new Point(x, y);\r
+       }\r
+\r
+       void resetCornerToNull() {\r
+               this.upperLeftCorner = null;\r
+               this.lowerRightCorner = null;\r
+\r
+       }\r
+\r
+       /**\r
+        * @see java.lang.Object#toString()\r
+        */\r
+       @Override\r
+       public String toString() {\r
+               return "ISItem [getText()=" + this.getText() + "]";\r
+       }\r
+\r
+       /**\r
+        * @see java.lang.Comparable#compareTo(java.lang.Object)\r
+        */\r
+       @Override\r
+       public int compareTo(final ISItem o) {\r
+               return new Double(Math.abs(this.zPosition)).compareTo(Math.abs(o.getzPosition())) * -1;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ImageSelector.java b/org.tizen.common.externals/src/org/mihalis/opal/imageSelector/ImageSelector.java
new file mode 100755 (executable)
index 0000000..2bab62d
--- /dev/null
@@ -0,0 +1,615 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *     Romain Guy - Original Swing Implementation (http://www.curious-creature.org/2005/07/09/a-music-shelf-in-java2d/)\r
+ *******************************************************************************/\r
+package org.mihalis.opal.imageSelector;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.KeyAdapter;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.MouseAdapter;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.events.MouseMoveListener;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are controls that allow the user to select images.\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * </dl>\r
+ */\r
+public class ImageSelector extends Canvas {\r
+       private List<ISItem> items;\r
+       private List<ISItem> originalItems;\r
+       private Font font;\r
+       private static final int DEFAULT_WIDTH = 148;\r
+       private int maxItemWidth = DEFAULT_WIDTH;\r
+       private int index = -1;\r
+       private double sigma;\r
+       private double rho;\r
+       private double expMultiplier;\r
+       private double expMember;\r
+       private float spacing = 0.4f;\r
+       private Color gradientStart;\r
+       private Color gradientEnd;\r
+       private double animationStep = -1d;\r
+       private static final int TIMER_INTERVAL = 50;\r
+       private int pageIncrement = 5;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       public ImageSelector(final Composite parent, final int style) {\r
+               super(parent, style | SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED);\r
+               this.font = new Font(this.getDisplay(), "Lucida Sans", 24, SWT.NONE);\r
+\r
+               this.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(ImageSelector.this.font);\r
+                               SWTGraphicUtil.dispose(ImageSelector.this.gradientStart);\r
+                               SWTGraphicUtil.dispose(ImageSelector.this.gradientEnd);\r
+                       }\r
+\r
+               });\r
+\r
+               addPaintListener(new PaintListener() {\r
+                       @Override\r
+                       public void paintControl(final PaintEvent e) {\r
+                               ImageSelector.this.paintControl(e);\r
+                       }\r
+\r
+               });\r
+\r
+               addKeyListener();\r
+               addMouseListeners();\r
+\r
+               setSigma(0.5);\r
+               this.gradientStart = new Color(getDisplay(), 0, 0, 0);\r
+               this.gradientEnd = new Color(getDisplay(), 110, 110, 110);\r
+       }\r
+\r
+       /**\r
+        * Set the sigma value for the gaussian curve\r
+        * \r
+        * @param sigma new sigma parameter\r
+        */\r
+       public void setSigma(final double sigma) {\r
+               this.sigma = sigma;\r
+               this.rho = 1.0;\r
+               computeEquationParts();\r
+               this.rho = computeModifierUnbounded(0.0);\r
+               computeEquationParts();\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * Computer both members of the equation\r
+        */\r
+       private void computeEquationParts() {\r
+               this.expMultiplier = Math.sqrt(2.0 * Math.PI) / this.sigma / this.rho;\r
+               this.expMember = 4.0 * this.sigma * this.sigma;\r
+       }\r
+\r
+       /**\r
+        * Compute the value of the modifier. The value is bounded between -1 and +1\r
+        * \r
+        * @param x input value\r
+        * @return the value of the modifier between -1 and +1\r
+        */\r
+       private double computeModifierBounded(final double x) {\r
+               double result = computeModifierUnbounded(x);\r
+               if (result > 1.0) {\r
+                       result = 1.0;\r
+               } else if (result < -1.0) {\r
+                       result = -1.0;\r
+               }\r
+               return result;\r
+       }\r
+\r
+       /**\r
+        * Compute the value of the modifier\r
+        * \r
+        * @param x input value\r
+        * @return the value of the function\r
+        */\r
+       private double computeModifierUnbounded(final double x) {\r
+               return this.expMultiplier * Math.exp(-x * x / this.expMember);\r
+       }\r
+\r
+       /**\r
+        * Draw the widget\r
+        * \r
+        * @param e the paintEvent\r
+        */\r
+       private void paintControl(final PaintEvent e) {\r
+\r
+               // Create the image to fill the canvas\r
+               final Image image = new Image(getDisplay(), getClientArea());\r
+\r
+               // Set up the offscreen gc\r
+               final GC gc = new GC(image);\r
+\r
+               // Draw gradient\r
+               drawBackground(gc);\r
+\r
+               // Draw the items\r
+               drawItems(gc);\r
+\r
+               // Draw the title\r
+               if (this.animationStep < 0d) {\r
+                       drawTitle(gc);\r
+               }\r
+\r
+               // Draw the offscreen buffer to the screen\r
+               e.gc.drawImage(image, 0, 0);\r
+\r
+               // Clean up\r
+               image.dispose();\r
+               gc.dispose();\r
+\r
+       }\r
+\r
+       /**\r
+        * Draw the background\r
+        * \r
+        * @param gc graphical context\r
+        */\r
+       private void drawBackground(final GC gc) {\r
+               final Rectangle rect = getClientArea();\r
+\r
+               gc.setForeground(this.gradientStart);\r
+               gc.setBackground(this.gradientEnd);\r
+               gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height / 2, true);\r
+\r
+               gc.setForeground(this.gradientEnd);\r
+               gc.setBackground(this.gradientStart);\r
+               gc.fillGradientRectangle(rect.x, rect.height / 2, rect.width, rect.height / 2, true);\r
+       }\r
+\r
+       /**\r
+        * Draw the items\r
+        * \r
+        * @param gc graphical context\r
+        */\r
+       private void drawItems(final GC gc) {\r
+\r
+               if (this.animationStep < 0d) {\r
+                       this.items.clear();\r
+                       this.items.addAll(this.originalItems);\r
+                       for (int i = 0; i < this.items.size(); i++) {\r
+                               final ISItem item = this.items.get(i);\r
+                               item.setzPosition((i - this.index) * this.spacing);\r
+                       }\r
+\r
+                       Collections.sort(this.items);\r
+               }\r
+\r
+               for (final ISItem item : this.items) {\r
+                       drawItem(gc, item);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Draw a given item\r
+        * \r
+        * @param gc graphical context\r
+        * @param item item to draw\r
+        */\r
+       private void drawItem(final GC gc, final ISItem item) {\r
+\r
+               final int size = computeSize(item);\r
+               final int centerX = computeZPosition(item);\r
+               final int centerY = this.getClientArea().height / 2;\r
+\r
+               if (size <= 0 || centerX < 0 || centerX > getBounds().width) {\r
+                       item.resetCornerToNull();\r
+                       return;\r
+               }\r
+\r
+               final int alpha = computeAlpha(item);\r
+\r
+               final Image newImage = SWTGraphicUtil.createReflectedResizedImage(item.getImage(), size, size);\r
+               gc.setAlpha(alpha);\r
+\r
+               final int x = centerX - newImage.getBounds().width / 2;\r
+               final int y = centerY - newImage.getBounds().height / 2;\r
+\r
+               gc.drawImage(newImage, x, y);\r
+\r
+               item.setUpperLeftCorner(x, y);\r
+               item.setLowerRightCorner(x + newImage.getBounds().width, (int) (y + newImage.getBounds().height / 1.5));\r
+\r
+               newImage.dispose();\r
+       }\r
+\r
+       /**\r
+        * Compute the z position for a given item\r
+        * \r
+        * @param item item\r
+        * @return the z position of the item\r
+        */\r
+       private int computeZPosition(final ISItem item) {\r
+               final int totalWidth = this.getClientArea().width / 2;\r
+               final int centerX = this.getClientArea().width / 2;\r
+               return (int) (centerX + item.getzPosition() * totalWidth);\r
+       }\r
+\r
+       /**\r
+        * Compute size for a given item\r
+        * \r
+        * @param item item\r
+        * @return the size of the item\r
+        */\r
+       private int computeSize(final ISItem item) {\r
+               return (int) (computeModifierBounded(item.getzPosition()) * this.maxItemWidth);\r
+       }\r
+\r
+       /**\r
+        * Compute the alpha value of a given item\r
+        * \r
+        * @param item item\r
+        * @return the alpha value of the item\r
+        */\r
+       private int computeAlpha(final ISItem item) {\r
+               return (int) (255 - 150 * Math.abs(item.getzPosition()));\r
+       }\r
+\r
+       /**\r
+        * Draw the title under the selected item\r
+        * \r
+        * @param gc graphical context\r
+        */\r
+       private void drawTitle(final GC gc) {\r
+               final String title = this.originalItems.get(this.index).getText();\r
+               if (title == null || title.trim().equals("")) {\r
+                       return;\r
+               }\r
+               gc.setFont(getFont());\r
+               final Point textSize = gc.stringExtent(title);\r
+\r
+               gc.setAntialias(SWT.ON);\r
+               gc.setFont(getFont());\r
+               gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+               gc.setAlpha(255);\r
+\r
+               final int centerX = this.getClientArea().width / 2;\r
+               final int centerY = (this.getClientArea().height + this.maxItemWidth) / 2;\r
+\r
+               gc.drawString(title, centerX - textSize.x / 2, (centerY - textSize.y / 2), true);\r
+\r
+       }\r
+\r
+       /**\r
+        * Add the key listener\r
+        */\r
+       private void addKeyListener() {\r
+               this.addKeyListener(new KeyAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent)\r
+                        */\r
+                       @Override\r
+                       public void keyReleased(final KeyEvent e) {\r
+                               switch (e.keyCode) {\r
+                               case SWT.ARROW_LEFT:\r
+                               case SWT.ARROW_UP:\r
+                                       scrollAndAnimateBy(-1);\r
+                                       break;\r
+                               case SWT.ARROW_RIGHT:\r
+                               case SWT.ARROW_DOWN:\r
+                                       scrollAndAnimateBy(1);\r
+                                       break;\r
+                               case SWT.HOME:\r
+                                       scrollBy(-1 * ImageSelector.this.index);\r
+                                       break;\r
+                               case SWT.END:\r
+                                       scrollBy(ImageSelector.this.index);\r
+                                       break;\r
+                               case SWT.PAGE_UP:\r
+                                       scrollBy(-1 * ImageSelector.this.pageIncrement);\r
+                                       break;\r
+                               case SWT.PAGE_DOWN:\r
+                                       scrollBy(ImageSelector.this.pageIncrement);\r
+                                       break;\r
+                default:\r
+                    break;\r
+                               }\r
+                       }\r
+\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Scroll the selected item\r
+        * \r
+        * @param increment increment value\r
+        */\r
+       private void scrollBy(final int increment) {\r
+               this.index += increment;\r
+               if (this.index < 0) {\r
+                       this.index = 0;\r
+               }\r
+\r
+               if (this.index >= this.items.size()) {\r
+                       this.index = this.items.size() - 1;\r
+               }\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * Scroll the selected item with an animation\r
+        * \r
+        * @param increment increment value\r
+        */\r
+       private void scrollAndAnimateBy(final int increment) {\r
+               if (this.index == 0 && increment < 0 || this.index == this.items.size() - 1 && increment > 0) {\r
+                       return;\r
+               }\r
+\r
+               final double step = Math.abs(increment) / (300d / TIMER_INTERVAL);\r
+               ImageSelector.this.animationStep = step;\r
+               setCursor(getDisplay().getSystemCursor(SWT.CURSOR_WAIT));\r
+\r
+               getDisplay().syncExec(new Runnable() {\r
+\r
+                       @Override\r
+                       public void run() {\r
+\r
+                               ImageSelector.this.items.clear();\r
+                               ImageSelector.this.items.addAll(ImageSelector.this.originalItems);\r
+                               for (int i = 0; i < ImageSelector.this.items.size(); i++) {\r
+                                       final ISItem item = ImageSelector.this.items.get(i);\r
+                                       item.setzPosition((i - ImageSelector.this.index + ImageSelector.this.animationStep * (increment > 0 ? -1d : 1d)) * ImageSelector.this.spacing);\r
+                               }\r
+                               Collections.sort(ImageSelector.this.items);\r
+                               if (!isDisposed()) {\r
+                                       redraw();\r
+                               }\r
+\r
+                               ImageSelector.this.animationStep += step;\r
+                               if (ImageSelector.this.animationStep >= 1d) {\r
+                                       ImageSelector.this.animationStep = -1d;\r
+                                       ImageSelector.this.index += increment;\r
+                                       setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW));\r
+                               } else {\r
+                                       if (!isDisposed()) {\r
+                                               getDisplay().timerExec(TIMER_INTERVAL, this);\r
+                                       }\r
+                               }\r
+\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Add mouse listeners\r
+        */\r
+       private void addMouseListeners() {\r
+               addMouseMoveListener(new MouseMoveListener() {\r
+\r
+                       @Override\r
+                       public void mouseMove(final MouseEvent e) {\r
+                               for (final ISItem item : ImageSelector.this.items) {\r
+                                       if (item.getUpperLeftCorner() != null && item.getLowerRightCorner() != null && e.x >= item.getUpperLeftCorner().x && e.x <= item.getLowerRightCorner().x && e.y >= item.getUpperLeftCorner().y && e.y <= item.getLowerRightCorner().y) {\r
+                                               setCursor(getDisplay().getSystemCursor(SWT.CURSOR_HAND));\r
+                                               return;\r
+                                       }\r
+                               }\r
+                               setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW));\r
+                       }\r
+               });\r
+\r
+               addMouseListener(new MouseAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent)\r
+                        */\r
+                       @Override\r
+                       public void mouseUp(final MouseEvent e) {\r
+                               for (final ISItem item : ImageSelector.this.items) {\r
+                                       if (item.getUpperLeftCorner() != null && item.getLowerRightCorner() != null && e.x >= item.getUpperLeftCorner().x && e.x <= item.getLowerRightCorner().x && e.y >= item.getUpperLeftCorner().y && e.y <= item.getLowerRightCorner().y) {\r
+                                               scrollAndAnimateBy(ImageSelector.this.originalItems.indexOf(item) - ImageSelector.this.index);\r
+                                               return;\r
+                                       }\r
+                               }\r
+                       }\r
+               });\r
+\r
+               addListener(SWT.MouseWheel, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               scrollBy(-1 * event.count);\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * @return the items displayed by this widget\r
+        */\r
+       public List<ISItem> getItems() {\r
+               return this.originalItems;\r
+       }\r
+\r
+       /**\r
+        * @param items the items that are displayed in this widget to set\r
+        */\r
+       public void setItems(final List<ISItem> items) {\r
+               this.items = new ArrayList<ISItem>(items);\r
+               this.originalItems = items;\r
+               this.index = this.items.size() / 2;\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * @return the font used for the title\r
+        */\r
+       @Override\r
+       public Font getFont() {\r
+               return this.font;\r
+       }\r
+\r
+       /**\r
+        * @param font the font used for the title to set\r
+        */\r
+       @Override\r
+       public void setFont(final Font font) {\r
+               SWTGraphicUtil.dispose(this.font);\r
+               this.font = font;\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * @return the index of the selected image\r
+        */\r
+       public int getIndex() {\r
+               return this.index;\r
+       }\r
+\r
+       /**\r
+        * @param index the index of the selected image to set\r
+        */\r
+       public void setIndex(final int index) {\r
+               this.index = index;\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * @return the maximum items width\r
+        */\r
+       public int getMaxItemWidth() {\r
+               return this.maxItemWidth;\r
+       }\r
+\r
+       /**\r
+        * @param maxItemWidth the the maximum items width to set\r
+        */\r
+       public void setMaxItemWidth(final int maxItemWidth) {\r
+               this.maxItemWidth = maxItemWidth;\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * @return the sigma value\r
+        */\r
+       public double getSigma() {\r
+               return this.sigma;\r
+       }\r
+\r
+       /**\r
+        * @return the spacing between 2 items\r
+        */\r
+       public float getSpacing() {\r
+               return this.spacing;\r
+       }\r
+\r
+       /**\r
+        * @param spacing the the spacing between 2 items to set\r
+        */\r
+       public void setSpacing(final float spacing) {\r
+               this.spacing = spacing;\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * @return the gradient start color\r
+        */\r
+       public Color getGradientStart() {\r
+               return this.gradientStart;\r
+       }\r
+\r
+       /**\r
+        * @param gradientStart the the gradient start color to set\r
+        */\r
+       public void setGradientStart(final Color gradientStart) {\r
+               SWTGraphicUtil.dispose(this.gradientStart);\r
+               this.gradientStart = gradientStart;\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * @return the the gradient end color\r
+        */\r
+       public Color getGradientEnd() {\r
+               return this.gradientEnd;\r
+       }\r
+\r
+       /**\r
+        * @param gradientEnd the the gradient end color to set\r
+        */\r
+       public void setGradientEnd(final Color gradientEnd) {\r
+               SWTGraphicUtil.dispose(this.gradientEnd);\r
+               this.gradientEnd = gradientEnd;\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * @return the page increment when the user uses PgUp and PgDown\r
+        */\r
+       public int getPageIncrement() {\r
+               return this.pageIncrement;\r
+       }\r
+\r
+       /**\r
+        * @param pageIncrement the page increment to set\r
+        */\r
+       public void setPageIncrement(final int pageIncrement) {\r
+               this.pageIncrement = pageIncrement;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/infinitePanel/InfiniteProgressPanel.java b/org.tizen.common.externals/src/org/mihalis/opal/infinitePanel/InfiniteProgressPanel.java
new file mode 100644 (file)
index 0000000..e7a62de
--- /dev/null
@@ -0,0 +1,604 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation, \r
+ *     inspired by Romain Guy's work (http://www.curious-creature.org)\r
+ *******************************************************************************/\r
+package org.mihalis.opal.infinitePanel;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are controls located on the top of a shell. They\r
+ * display a ticker that indicates to the user that a long task operation is\r
+ * running\r
+ */\r
+public class InfiniteProgressPanel {\r
+\r
+       private static final String INFINITE_PANEL_KEY = "org.mihalis.opal.InfinitePanel.InfiniteProgressPanel";\r
+       private static final int NUMBER_OF_STEPS = 10;\r
+\r
+       private final Shell parent;\r
+       private Shell panel;\r
+       private String text;\r
+       private Font textFont;\r
+       private Color textColor;\r
+       private float fps;\r
+       private int barsCount;\r
+       private int lineWidth;\r
+       private int alpha;\r
+       private Color defaultColor;\r
+       private Color selectionColor;\r
+       private int currentPosition;\r
+       private Thread animatorThread;\r
+       private Canvas canvas;\r
+       private boolean fadeIn;\r
+       private boolean fadeOut;\r
+       private int fadeOutCounter;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent.\r
+        * \r
+        * @param shell a shell that will be the parent of the new instance (cannot\r
+        *            be null)\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the parent has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        */\r
+       private InfiniteProgressPanel(final Shell shell) {\r
+               if (shell == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (shell.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+\r
+               this.parent = shell;\r
+               if (shell.getData(INFINITE_PANEL_KEY) != null) {\r
+                       throw new IllegalArgumentException("This shell has already an infinite panel attached on it !");\r
+               }\r
+\r
+               this.text = null;\r
+               this.textFont = null;\r
+               this.barsCount = 14;\r
+               this.fps = 15.0f;\r
+               this.lineWidth = 16;\r
+               this.alpha = 200;\r
+               this.fadeIn = false;\r
+               this.fadeOut = false;\r
+               this.fadeOutCounter = 0;\r
+               shell.setData(INFINITE_PANEL_KEY, this);\r
+\r
+               this.parent.addListener(SWT.Activate, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event e) {\r
+                               if (InfiniteProgressPanel.this.panel != null && //\r
+                                               !InfiniteProgressPanel.this.panel.isDisposed() && !InfiniteProgressPanel.this.panel.isVisible()) {\r
+                                       InfiniteProgressPanel.this.panel.setVisible(true);\r
+                                       InfiniteProgressPanel.this.panel.setActive();\r
+                               }\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Starts the ticker\r
+        */\r
+       public void start() {\r
+               if (this.parent.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               this.panel = new Shell(this.parent, SWT.APPLICATION_MODAL | SWT.NO_TRIM | SWT.ON_TOP);\r
+               this.panel.setLayout(new FillLayout());\r
+               this.panel.setAlpha(0);\r
+\r
+               this.panel.addListener(SWT.KeyUp, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               event.doit = false;\r
+                       }\r
+               });\r
+\r
+               if (this.defaultColor == null) {\r
+                       this.defaultColor = new Color(this.parent.getDisplay(), 200, 200, 200);\r
+               }\r
+\r
+               if (this.selectionColor == null) {\r
+                       this.selectionColor = new Color(this.parent.getDisplay(), 0, 0, 0);\r
+               }\r
+\r
+               this.parent.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(InfiniteProgressPanel.this.defaultColor);\r
+                               SWTGraphicUtil.dispose(InfiniteProgressPanel.this.selectionColor);\r
+                       }\r
+               });\r
+\r
+               this.currentPosition = 0;\r
+               this.fadeIn = true;\r
+               this.fadeOut = false;\r
+               this.fadeOutCounter = 0;\r
+\r
+               this.canvas = new Canvas(this.panel, SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED);\r
+               this.canvas.addPaintListener(new PaintListener() {\r
+\r
+                       @Override\r
+                       public void paintControl(final PaintEvent e) {\r
+                               InfiniteProgressPanel.this.paintCanvas(e);\r
+                       }\r
+               });\r
+\r
+               this.panel.setBounds(this.panel.getDisplay().map(this.parent, null, this.parent.getClientArea()));\r
+               this.panel.open();\r
+\r
+               this.animatorThread = new Thread() {\r
+\r
+                       /**\r
+                        * @see java.lang.Thread#run()\r
+                        */\r
+                       @Override\r
+                       public void run() {\r
+                               while (!Thread.interrupted()) {\r
+                                       InfiniteProgressPanel.this.currentPosition = (InfiniteProgressPanel.this.currentPosition + 1) % InfiniteProgressPanel.this.barsCount;\r
+                                       if (InfiniteProgressPanel.this.fadeOut) {\r
+                                               InfiniteProgressPanel.this.fadeOutCounter++;\r
+                                       }\r
+                                       InfiniteProgressPanel.this.panel.getDisplay().asyncExec(new Runnable() {\r
+\r
+                                               @Override\r
+                                               public void run() {\r
+                                                       InfiniteProgressPanel.this.canvas.redraw();\r
+                                               }\r
+                                       });\r
+\r
+                                       try {\r
+                                               sleep(InfiniteProgressPanel.this.fadeOut ? 20 : (long) (1000 / InfiniteProgressPanel.this.fps));\r
+                                       } catch (final InterruptedException e) {\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+               };\r
+               this.animatorThread.start();\r
+\r
+               this.panel.addListener(SWT.Deactivate, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event arg0) {\r
+                               InfiniteProgressPanel.this.panel.setVisible(false);\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Paint the canvas that holds the ticker\r
+        * \r
+        * @param e\r
+        */\r
+       private void paintCanvas(final PaintEvent e) {\r
+               // Paint the panel\r
+               final Rectangle clientArea = ((Canvas) e.widget).getClientArea();\r
+               final GC gc = e.gc;\r
+\r
+               this.handleFadeIn();\r
+               this.handleFadeOut();\r
+               this.drawBackground(clientArea, gc);\r
+               this.drawTicker(clientArea, gc);\r
+               this.drawText(clientArea, gc);\r
+\r
+       }\r
+\r
+       /**\r
+        * Handle the fade in effect of the panel\r
+        */\r
+       private void handleFadeIn() {\r
+               if (this.fadeIn) {\r
+                       if (this.currentPosition == NUMBER_OF_STEPS) {\r
+                               this.fadeIn = false;\r
+                               this.panel.setAlpha(this.alpha);\r
+                       } else {\r
+                               this.panel.setAlpha(this.currentPosition * this.alpha / NUMBER_OF_STEPS);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Handle the fade out effect of the panel\r
+        */\r
+       private void handleFadeOut() {\r
+               if (this.fadeOut) {\r
+                       if (this.fadeOutCounter == NUMBER_OF_STEPS) {\r
+                               if (this.animatorThread != null) {\r
+                                       this.animatorThread.interrupt();\r
+                                       this.animatorThread = null;\r
+                               }\r
+                               if (!this.panel.isDisposed()) {\r
+                                       this.panel.getDisplay().asyncExec(new Runnable() {\r
+\r
+                                               @Override\r
+                                               public void run() {\r
+                                                       if (!InfiniteProgressPanel.this.panel.isDisposed()) {\r
+                                                               InfiniteProgressPanel.this.panel.dispose();\r
+                                                       }\r
+                                               }\r
+                                       });\r
+                               }\r
+                       }\r
+                       this.panel.setAlpha(255 - this.fadeOutCounter * this.alpha / NUMBER_OF_STEPS);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Draw the background of the panel\r
+        * \r
+        * @param gc GC on with the background is drawn\r
+        * @param clientArea client area of the canvas\r
+        */\r
+       private void drawBackground(final Rectangle clientArea, final GC gc) {\r
+               // Draw the background\r
+               gc.setBackground(this.panel.getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+               gc.fillRectangle(clientArea);\r
+       }\r
+\r
+       /**\r
+        * Draw the ticker\r
+        * \r
+        * @param gc GC on with the ticker is drawn\r
+        * @param clientArea client area of the canvas\r
+        */\r
+       private void drawTicker(final Rectangle clientArea, final GC gc) {\r
+               // Draw the ticker\r
+               final int centerX = clientArea.width / 2;\r
+               final int centerY = clientArea.height / 2;\r
+               final int maxRay = (int) (Math.min(clientArea.width, clientArea.height) * 0.6f) / 2;\r
+               final int minRay = (int) (maxRay * 0.5f);\r
+\r
+               double angle = Math.PI / 2;\r
+\r
+               gc.setLineCap(SWT.CAP_ROUND);\r
+               gc.setLineWidth(this.lineWidth);\r
+               gc.setAntialias(SWT.ON);\r
+\r
+               for (int i = 0; i < this.barsCount; i++) {\r
+                       if (i == this.currentPosition) {\r
+                               gc.setForeground(this.selectionColor);\r
+                       } else {\r
+                               gc.setForeground(this.defaultColor);\r
+                       }\r
+                       gc.drawLine((int) (centerX + minRay * Math.cos(angle)), //\r
+                                       (int) (centerY - minRay * Math.sin(angle)), //\r
+                                       (int) (centerX + maxRay * Math.cos(angle)), //\r
+                                       (int) (centerY - maxRay * Math.sin(angle)));\r
+                       angle -= 2 * Math.PI / this.barsCount;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Draw the text over the ticker\r
+        * \r
+        * @param gc GC on with the text is drawn\r
+        * @param clientArea client area of the canvas\r
+        */\r
+       private void drawText(final Rectangle clientArea, final GC gc) {\r
+               if (this.text == null || "".equals(this.text)) {\r
+                       return;\r
+               }\r
+\r
+               final Font font;\r
+               if (this.textFont == null) {\r
+                       font = this.parent.getDisplay().getSystemFont();\r
+               } else {\r
+                       font = this.textFont;\r
+               }\r
+\r
+               final Color color;\r
+               if (this.textColor == null) {\r
+                       color = this.parent.getDisplay().getSystemColor(SWT.COLOR_BLACK);\r
+               } else {\r
+                       color = this.textColor;\r
+               }\r
+\r
+               gc.setForeground(color);\r
+               gc.setFont(font);\r
+               gc.setTextAntialias(SWT.ON);\r
+               final Point textSize = gc.textExtent(this.text, SWT.DRAW_TRANSPARENT);\r
+               final int textWidth = textSize.x;\r
+               final int textHeight = textSize.y;\r
+\r
+               gc.drawString(this.text, (clientArea.width - textWidth) / 2, (clientArea.height - textHeight) / 2, true);\r
+\r
+       }\r
+\r
+       /**\r
+        * Stop the animation and dispose the panel\r
+        */\r
+       public void stop() {\r
+               if (this.panel.isDisposed() || this.panel.getDisplay().isDisposed()) {\r
+                       return;\r
+               }\r
+               this.fadeOut = true;\r
+       }\r
+\r
+       /**\r
+        * Returns the infinite progress panel for the shell. If no infinite panel\r
+        * has been declared, returns null.\r
+        * \r
+        * @param shell the shell for which we are trying to get the associated\r
+        *            progess panel\r
+        * @return the progress panel associated to shell, or null if there is no\r
+        *         progress panel\r
+        */\r
+       public static InfiniteProgressPanel getInfiniteProgressPanelFor(final Shell shell) {\r
+               if (shell == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (shell.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               if (shell.getDisplay().isDisposed()) {\r
+                       SWT.error(SWT.ERROR_DEVICE_DISPOSED);\r
+               }\r
+\r
+               final InfiniteProgressPanel[] temp = new InfiniteProgressPanel[1];\r
+               shell.getDisplay().syncExec(new Runnable() {\r
+\r
+                       @Override\r
+                       public void run() {\r
+                               final Object data = shell.getData(INFINITE_PANEL_KEY);\r
+                               if (data != null && data instanceof InfiniteProgressPanel) {\r
+                                       temp[0] = (InfiniteProgressPanel) data;\r
+                               }\r
+                       }\r
+               });\r
+\r
+               if (temp[0] == null) {\r
+                       return new InfiniteProgressPanel(shell);\r
+               } else {\r
+                       return temp[0];\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Check if a shell has an associated progress panel\r
+        * \r
+        * @param shell the shell\r
+        * @return <code>true</code> if the shell has an associated panel,\r
+        *         <code>false</code> otherwise\r
+        */\r
+       public static boolean hasInfiniteProgressPanel(final Shell shell) {\r
+               return getInfiniteProgressPanelFor(shell) != null;\r
+       }\r
+\r
+       // ------------------------------------------------- Getters and Setters\r
+\r
+       /**\r
+        * @return the alpha value of the panel\r
+        */\r
+       public int getAlpha() {\r
+               return this.alpha;\r
+       }\r
+\r
+       /**\r
+        * @param alpha the alpha value of the panel, between 0 and 255\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the animation is running</li>\r
+        *                </ul>\r
+        */\r
+       public void setAlpha(final int alpha) {\r
+               if (alpha < 0 || alpha > 255) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+               this.checkIfAnimationIsRunning();\r
+               this.alpha = alpha;\r
+       }\r
+\r
+       /**\r
+        * Check if the animation is running\r
+        */\r
+       private void checkIfAnimationIsRunning() {\r
+               if (this.animatorThread != null) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, "Can not change this value when an animation is running");\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return the number of bars displayed in the ticker\r
+        */\r
+       public int getBarsCount() {\r
+               return this.barsCount;\r
+       }\r
+\r
+       /**\r
+        * @param barsCount the number of bars displayed in the ticker\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the animation is running</li>\r
+        *                </ul>\r
+        */\r
+       public void setBarsCount(final int barsCount) {\r
+               this.checkIfAnimationIsRunning();\r
+               this.barsCount = barsCount;\r
+       }\r
+\r
+       /**\r
+        * @return the default color for the ticker's bars\r
+        */\r
+       public Color getDefaultColor() {\r
+               return this.defaultColor;\r
+       }\r
+\r
+       /**\r
+        * @param defaultColor the new default color for the ticker's bars. Please\r
+        *            notice that the previous color is disposed.\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the animation is running</li>\r
+        *                </ul>\r
+        */\r
+       public void setDefaultColor(final Color defaultColor) {\r
+               this.checkIfAnimationIsRunning();\r
+               SWTGraphicUtil.dispose(this.defaultColor);\r
+               this.defaultColor = defaultColor;\r
+       }\r
+\r
+       /**\r
+        * @return the number of frame per second for the animation\r
+        */\r
+       public float getFps() {\r
+               return this.fps;\r
+       }\r
+\r
+       /**\r
+        * @param fps the new frame per second value\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the animation is running</li>\r
+        *                </ul>\r
+        */\r
+       public void setFps(final float fps) {\r
+               this.checkIfAnimationIsRunning();\r
+               this.fps = fps;\r
+       }\r
+\r
+       /**\r
+        * @return the line width of the bars that compose the ticker\r
+        */\r
+       public int getLineWidth() {\r
+               return this.lineWidth;\r
+       }\r
+\r
+       /**\r
+        * @param lineWidth the line width of the bars that compose the ticker\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the animation is running</li>\r
+        *                </ul>\r
+        */\r
+       public void setLineWidth(final int lineWidth) {\r
+               this.checkIfAnimationIsRunning();\r
+               this.lineWidth = lineWidth;\r
+       }\r
+\r
+       /**\r
+        * @return the selection color of the ticker's bars\r
+        */\r
+       public Color getSelectionColor() {\r
+               return this.selectionColor;\r
+       }\r
+\r
+       /**\r
+        * @param selectionColor the new selection color for the ticker's bars.\r
+        *            Please notice that the previous color is disposed.\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the animation is running</li>\r
+        *                </ul>\r
+        */\r
+       public void setSelectionColor(final Color selectionColor) {\r
+               this.checkIfAnimationIsRunning();\r
+               SWTGraphicUtil.dispose(this.selectionColor);\r
+               this.selectionColor = selectionColor;\r
+       }\r
+\r
+       /**\r
+        * @return the displayed text\r
+        */\r
+       public String getText() {\r
+               return this.text;\r
+       }\r
+\r
+       /**\r
+        * @param text set the text to display\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the animation is running</li>\r
+        *                </ul>\r
+        */\r
+       public void setText(final String text) {\r
+               this.checkIfAnimationIsRunning();\r
+               this.text = text;\r
+       }\r
+\r
+       /**\r
+        * @return the text color\r
+        */\r
+       public Color getTextColor() {\r
+               return this.textColor;\r
+       }\r
+\r
+       /**\r
+        * @param textColor the text color. Please notice that the previous color is\r
+        *            disposed.\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the animation is running</li>\r
+        *                </ul>\r
+        */\r
+       public void setTextColor(final Color textColor) {\r
+               this.checkIfAnimationIsRunning();\r
+               SWTGraphicUtil.dispose(this.textColor);\r
+               this.textColor = textColor;\r
+       }\r
+\r
+       /**\r
+        * @return the text font\r
+        */\r
+       public Font getTextFont() {\r
+               return this.textFont;\r
+       }\r
+\r
+       /**\r
+        * @param textFont the new text font. Please notice that the previous font\r
+        *            set is disposed.\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the animation is running</li>\r
+        *                </ul>\r
+        */\r
+       public void setTextFont(final Font textFont) {\r
+               this.checkIfAnimationIsRunning();\r
+               if (this.textFont != null && !this.textFont.isDisposed()) {\r
+                       this.textFont.dispose();\r
+               }\r
+               this.textFont = textFont;\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DLItem.java b/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DLItem.java
new file mode 100644 (file)
index 0000000..953226f
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.itemSelector;\r
+\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.mihalis.opal.OpalItem;\r
+\r
+/**\r
+ * Instances of this class represents items manipulated by this DualList widget\r
+ */\r
+public class DLItem extends OpalItem {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param text the text displayed in the DualList widget for this item\r
+        */\r
+       public DLItem(final String text) {\r
+               this.setText(text);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param text the text displayed in the DualList widget for this item\r
+        * @param image the image displayed in the DualList widget for this item\r
+        */\r
+       public DLItem(final String text, final Image image) {\r
+               this.setText(text);\r
+               this.setImage(image);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param text the text displayed in the DualList widget for this item\r
+        * @param image the image displayed in the DualList widget for this item\r
+        * @param font the font displayed in the DualList widget for this item\r
+        * @param foregroundColor the foreground color displayed in the DualList\r
+        *            widget for this item\r
+        */\r
+       public DLItem(final String text, final Image image, final Font font, final Color foregroundColor) {\r
+               this.setText(text);\r
+               this.setImage(image);\r
+               this.setFont(font);\r
+               this.setForeground(foregroundColor);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param text the text displayed in the DualList widget for this item\r
+        * @param image the image displayed in the DualList widget for this item\r
+        * @param foregroundColor the foreground color displayed in the DualList\r
+        *            widget for this item\r
+        * @param backgroundColor the background color displayed in the DualList\r
+        *            widget for this item\r
+        */\r
+       public DLItem(final String text, final Image image, final Color foregroundColor, final Color backgroundColor) {\r
+               this.setText(text);\r
+               this.setImage(image);\r
+               this.setForeground(foregroundColor);\r
+               this.setBackground(backgroundColor);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param text the text displayed in the DualList widget for this item\r
+        * @param image the image displayed in the DualList widget for this item\r
+        * @param font the font displayed in the DualList widget for this item\r
+        */\r
+       public DLItem(final String text, final Image image, final Font font) {\r
+               this.setText(text);\r
+               this.setImage(image);\r
+               this.setFont(font);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.OpalItem#getHeight()\r
+        */\r
+       @Override\r
+       public int getHeight() {\r
+               throw new UnsupportedOperationException("DLItem does not support this method");\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.OpalItem#setHeight(int)\r
+        */\r
+       @Override\r
+       public void setHeight(final int height) {\r
+               throw new UnsupportedOperationException("DLItem does not support this method");\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DualList.java b/org.tizen.common.externals/src/org/mihalis/opal/itemSelector/DualList.java
new file mode 100644 (file)
index 0000000..8b6b902
--- /dev/null
@@ -0,0 +1,1265 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.itemSelector;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.MouseAdapter;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+import org.mihalis.opal.utils.SimpleSelectionAdapter;\r
+\r
+/**\r
+ * Instances of this class are controls that allow the user to select multiple\r
+ * elements.\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>Selection</dd>\r
+ * </dl>\r
+ */\r
+\r
+public class DualList extends Composite {\r
+\r
+       private final List<DLItem> items;\r
+       private final List<DLItem> selection;\r
+\r
+       private final Table itemsTable;\r
+       private final Table selectionTable;\r
+\r
+       private List<SelectionListener> eventTable;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       public DualList(final Composite parent, final int style) {\r
+               super(parent, style);\r
+               this.items = new ArrayList<DLItem>();\r
+               this.selection = new ArrayList<DLItem>();\r
+\r
+               this.setLayout(new GridLayout(4, false));\r
+               this.itemsTable = this.createTable();\r
+               this.itemsTable.addMouseListener(new MouseAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.MouseAdapter#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)\r
+                        */\r
+                       @Override\r
+                       public void mouseDoubleClick(final MouseEvent event) {\r
+                               DualList.this.selectItem();\r
+                       }\r
+\r
+               });\r
+               final Button buttonSelectAll = this.createButton("double_right.png", true, GridData.END);\r
+               buttonSelectAll.addSelectionListener(new SimpleSelectionAdapter() {\r
+\r
+                       @Override\r
+                       public void handle(final SelectionEvent e) {\r
+                               DualList.this.selectAll();\r
+                       }\r
+               });\r
+\r
+               this.selectionTable = this.createTable();\r
+               this.selectionTable.addMouseListener(new MouseAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.MouseAdapter#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)\r
+                        */\r
+                       @Override\r
+                       public void mouseDoubleClick(final MouseEvent event) {\r
+                               DualList.this.deselectItem();\r
+                       }\r
+\r
+               });\r
+\r
+               final Button buttonMoveFirst = this.createButton("double_up.png", true, GridData.END);\r
+               buttonMoveFirst.addSelectionListener(new SimpleSelectionAdapter() {\r
+\r
+                       @Override\r
+                       public void handle(final SelectionEvent e) {\r
+                               DualList.this.moveSelectionToFirstPosition();\r
+                       }\r
+               });\r
+\r
+               final Button buttonSelect = this.createButton("arrow_right.png", false, GridData.CENTER);\r
+               buttonSelect.addSelectionListener(new SimpleSelectionAdapter() {\r
+\r
+                       @Override\r
+                       public void handle(final SelectionEvent e) {\r
+                               DualList.this.selectItem();\r
+                       }\r
+               });\r
+\r
+               final Button buttonMoveUp = this.createButton("arrow_up.png", false, GridData.CENTER);\r
+               buttonMoveUp.addSelectionListener(new SimpleSelectionAdapter() {\r
+\r
+                       @Override\r
+                       public void handle(final SelectionEvent e) {\r
+                               DualList.this.moveUpItem();\r
+                       }\r
+               });\r
+\r
+               final Button buttonDeselect = this.createButton("arrow_left.png", false, GridData.CENTER);\r
+               buttonDeselect.addSelectionListener(new SimpleSelectionAdapter() {\r
+\r
+                       @Override\r
+                       public void handle(final SelectionEvent e) {\r
+                               DualList.this.deselectItem();\r
+                       }\r
+               });\r
+\r
+               final Button buttonMoveDown = this.createButton("arrow_down.png", false, GridData.CENTER);\r
+               buttonMoveDown.addSelectionListener(new SimpleSelectionAdapter() {\r
+\r
+                       @Override\r
+                       public void handle(final SelectionEvent e) {\r
+                               DualList.this.moveDownItem();\r
+                       }\r
+               });\r
+\r
+               final Button buttonDeselectAll = this.createButton("double_left.png", false, GridData.BEGINNING);\r
+               buttonDeselectAll.addSelectionListener(new SimpleSelectionAdapter() {\r
+\r
+                       @Override\r
+                       public void handle(final SelectionEvent e) {\r
+                               DualList.this.deselectAll();\r
+                       }\r
+               });\r
+\r
+               final Button buttonMoveLast = this.createButton("double_down.png", true, GridData.BEGINNING);\r
+               buttonMoveLast.addSelectionListener(new SimpleSelectionAdapter() {\r
+\r
+                       @Override\r
+                       public void handle(final SelectionEvent e) {\r
+                               DualList.this.moveSelectionToLastPosition();\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * @return a table that will contain data\r
+        */\r
+       private Table createTable() {\r
+               final Table table = new Table(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);\r
+               table.setLinesVisible(false);\r
+               table.setHeaderVisible(false);\r
+               final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 4);\r
+               gd.widthHint = 200;\r
+               table.setLayoutData(gd);\r
+               new TableColumn(table, SWT.CENTER);\r
+               new TableColumn(table, SWT.LEFT);\r
+               table.setData(-1);\r
+               return table;\r
+       }\r
+\r
+       /**\r
+        * Create a button\r
+        * \r
+        * @param fileName file name of the icon\r
+        * @param verticalExpand if <code>true</code>, the button will take all the\r
+        *            available space vertically\r
+        * @param alignment button alignment\r
+        * @return a new button\r
+        */\r
+       private Button createButton(final String fileName, final boolean verticalExpand, final int alignment) {\r
+               final Button button = new Button(this, SWT.PUSH);\r
+               final Image image = new Image(this.getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/" + fileName));\r
+               button.setImage(image);\r
+               button.setLayoutData(new GridData(GridData.CENTER, alignment, false, verticalExpand));\r
+               button.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(image);\r
+                       }\r
+               });\r
+               return button;\r
+       }\r
+\r
+       /**\r
+        * Adds the argument to the end of the receiver's list.\r
+        * \r
+        * @param item the new item\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the item is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see #add(DLItem,int)\r
+        */\r
+       public void add(final DLItem item) {\r
+               this.checkWidget();\r
+               if (item == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               this.items.add(item);\r
+       }\r
+\r
+       /**\r
+        * Adds the argument to the receiver's list at the given zero-relative\r
+        * index.\r
+        * <p>\r
+        * Note: To add an item at the end of the list, use the result of calling\r
+        * <code>getItemCount()</code> as the index or use <code>add(DLItem)</code>.\r
+        * </p>\r
+        * \r
+        * @param item the new item\r
+        * @param index the index for the item\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the item is null</li>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list (inclusive)</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see #add(String)\r
+        */\r
+       public void add(final DLItem item, final int index) {\r
+               this.checkWidget();\r
+               if (item == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               if (index <= 0 || index >= this.items.size()) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+               this.items.add(index, item);\r
+       }\r
+\r
+       /**\r
+        * Adds the listener to the collection of listeners who will be notified\r
+        * when the user changes the receiver's selection, by sending it one of the\r
+        * messages defined in the <code>SelectionListener</code> interface.\r
+        * \r
+        * @param listener the listener which should be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #removeSelectionListener\r
+        * @see SelectionEvent\r
+        */\r
+       public void addSelectionListener(final SelectionListener listener) {\r
+               this.checkWidget();\r
+               if (listener == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               if (this.eventTable == null) {\r
+                       this.eventTable = new ArrayList<SelectionListener>();\r
+               }\r
+               this.eventTable.add(listener);\r
+       }\r
+\r
+       /**\r
+        * Removes the listener from the collection of listeners who will be\r
+        * notified when the user changes the receiver's selection.\r
+        * \r
+        * @param listener the listener which should no longer be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #addSelectionListener\r
+        */\r
+       public void removeSelectionListener(final SelectionListener listener) {\r
+               this.checkWidget();\r
+               if (listener == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               if (this.eventTable == null) {\r
+                       return;\r
+               }\r
+               this.eventTable.remove(listener);\r
+       }\r
+\r
+       /**\r
+        * Deselects the item at the given zero-relative index in the receiver. If\r
+        * the item at the index was already deselected, it remains deselected.\r
+        * Indices that are out of range are ignored.\r
+        * \r
+        * @param index the index of the item to deselect\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void deselect(final int index) {\r
+               this.checkWidget();\r
+               if (index <= 0 || index >= this.items.size()) {\r
+                       return;\r
+               }\r
+               this.fireEvents(this.selection.remove(index));\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Deselects the items at the given zero-relative indices in the receiver.\r
+        * If the item at the given zero-relative index in the receiver is selected,\r
+        * it is deselected. If the item at the index was not selected, it remains\r
+        * deselected. Indices that are out of range and duplicate indices are\r
+        * ignored.\r
+        * \r
+        * @param indices the array of indices for the items to deselect\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the set of indices is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void deselect(final int[] indices) {\r
+               this.checkWidget();\r
+               if (indices == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               final List<DLItem> toBeRemoved = new ArrayList<DLItem>();\r
+\r
+               for (final int index : indices) {\r
+                       if (index <= 0 || index >= this.items.size()) {\r
+                               continue;\r
+                       }\r
+                       toBeRemoved.add(this.selection.get(index));\r
+               }\r
+\r
+               for (final DLItem item : toBeRemoved) {\r
+                       this.selection.remove(item);\r
+               }\r
+               toBeRemoved.clear();\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Deselects the items at the given zero-relative indices in the receiver.\r
+        * If the item at the given zero-relative index in the receiver is selected,\r
+        * it is deselected. If the item at the index was not selected, it remains\r
+        * deselected. The range of the indices is inclusive. Indices that are out\r
+        * of range are ignored.\r
+        * \r
+        * @param start the start index of the items to deselect\r
+        * @param end the end index of the items to deselect\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if start is greater than end</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void deselect(final int start, final int end) {\r
+               this.checkWidget();\r
+               if (start > end) {\r
+                       SWT.error(SWT.ERROR_INVALID_RANGE);\r
+               }\r
+               final List<DLItem> toBeRemoved = new ArrayList<DLItem>();\r
+\r
+               for (int index = start; index <= end; index++) {\r
+                       if (index <= 0 || index >= this.items.size()) {\r
+                               continue;\r
+                       }\r
+                       toBeRemoved.add(this.selection.get(index));\r
+               }\r
+\r
+               for (final DLItem item : toBeRemoved) {\r
+                       this.selection.remove(item);\r
+               }\r
+               toBeRemoved.clear();\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Deselects all selected items in the receiver.\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void deselectAll() {\r
+               this.checkWidget();\r
+               this.items.addAll(this.selection);\r
+               this.selection.clear();\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Returns the item at the given, zero-relative index in the receiver.\r
+        * Throws an exception if the index is out of range.\r
+        * \r
+        * @param index the index of the item to return\r
+        * @return the item at the given index\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+\r
+       public DLItem getItem(final int index) {\r
+               this.checkWidget();\r
+               if (index <= 0 || index >= this.items.size()) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+               return this.items.get(index);\r
+       }\r
+\r
+       /**\r
+        * Returns the number of items contained in the receiver.\r
+        * \r
+        * @return the number of items\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getItemCount() {\r
+               this.checkWidget();\r
+               return this.items.size();\r
+       }\r
+\r
+       /**\r
+        * Returns a (possibly empty) array of <code>DLItem</code>s which are the\r
+        * items in the receiver.\r
+        * <p>\r
+        * Note: This is not the actual structure used by the receiver to maintain\r
+        * its list of items, so modifying the array will not affect the receiver.\r
+        * </p>\r
+        * \r
+        * @return the items in the receiver's list\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public DLItem[] getItems() {\r
+               this.checkWidget();\r
+               return this.items.toArray(new DLItem[this.items.size()]);\r
+       }\r
+\r
+       /**\r
+        * Returns a (possibly empty) list of <code>DLItem</code>s which are the\r
+        * items in the receiver.\r
+        * <p>\r
+        * Note: This is not the actual structure used by the receiver to maintain\r
+        * its list of items, so modifying the array will not affect the receiver.\r
+        * </p>\r
+        * \r
+        * @return the items in the receiver's list\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public List<DLItem> getItemsAsList() {\r
+               this.checkWidget();\r
+               return new ArrayList<DLItem>(this.items);\r
+       }\r
+\r
+       /**\r
+        * Returns an array of <code>DLItem</code>s that are currently selected in\r
+        * the receiver. An empty array indicates that no items are selected.\r
+        * <p>\r
+        * Note: This is not the actual structure used by the receiver to maintain\r
+        * its selection, so modifying the array will not affect the receiver.\r
+        * </p>\r
+        * \r
+        * @return an array representing the selection\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public DLItem[] getSelection() {\r
+               this.checkWidget();\r
+               return this.selection.toArray(new DLItem[this.items.size()]);\r
+       }\r
+\r
+       /**\r
+        * Returns a list of <code>DLItem</code>s that are currently selected in the\r
+        * receiver. An empty array indicates that no items are selected.\r
+        * <p>\r
+        * Note: This is not the actual structure used by the receiver to maintain\r
+        * its selection, so modifying the array will not affect the receiver.\r
+        * </p>\r
+        * \r
+        * @return an array representing the selection\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public List<DLItem> getSelectionAsList() {\r
+               this.checkWidget();\r
+               return new ArrayList<DLItem>(this.selection);\r
+       }\r
+\r
+       /**\r
+        * Returns the number of selected items contained in the receiver.\r
+        * \r
+        * @return the number of selected items\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getSelectionCount() {\r
+               this.checkWidget();\r
+               return this.selection.size();\r
+       }\r
+\r
+       /**\r
+        * Removes the item from the receiver at the given zero-relative index.\r
+        * \r
+        * @param index the index for the item\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void remove(final int index) {\r
+               this.checkWidget();\r
+               if (index <= 0 || index >= this.items.size()) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+               this.items.remove(index);\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Removes the items from the receiver at the given zero-relative indices.\r
+        * \r
+        * @param indices the array of indices of the items\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the indices array is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void remove(final int[] indices) {\r
+               this.checkWidget();\r
+               for (final int index : indices) {\r
+                       if (index <= 0 || index >= this.items.size()) {\r
+                               SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+                       }\r
+                       this.items.remove(index);\r
+               }\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Removes the items from the receiver which are between the given\r
+        * zero-relative start and end indices (inclusive).\r
+        * \r
+        * @param start the start of the range\r
+        * @param end the end of the range\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if either the start or end are\r
+        *                not between 0 and the number of elements in the list minus\r
+        *                1 (inclusive) or if start>end</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void remove(final int start, final int end) {\r
+               this.checkWidget();\r
+               if (start > end) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+               for (int index = start; index <= end; index++) {\r
+                       if (index <= 0 || index >= this.items.size()) {\r
+                               SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+                       }\r
+                       this.items.remove(index);\r
+               }\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Searches the receiver's list starting at the first item until an item is\r
+        * found that is equal to the argument, and removes that item from the list.\r
+        * \r
+        * @param item the item to remove\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the item is null</li>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the item is not found in\r
+        *                the list</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void remove(final DLItem item) {\r
+               this.checkWidget();\r
+               if (item == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               if (!this.items.contains(item)) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+               this.items.remove(item);\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Removes all of the items from the receiver.\r
+        * <p>\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not\r
+        *                called from the thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void removeAll() {\r
+               this.checkWidget();\r
+               this.items.clear();\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Selects the item at the given zero-relative index in the receiver's list.\r
+        * If the item at the index was already selected, it remains selected.\r
+        * Indices that are out of range are ignored.\r
+        * \r
+        * @param index the index of the item to select\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void select(final int index) {\r
+               this.checkWidget();\r
+               if (index <= 0 || index >= this.items.size()) {\r
+                       return;\r
+               }\r
+               this.selection.add(this.items.get(index));\r
+               this.fireEvents(this.items.get(index));\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Selects the items at the given zero-relative indices in the receiver. The\r
+        * current selection is not cleared before the new items are selected.\r
+        * <p>\r
+        * If the item at a given index is not selected, it is selected. If the item\r
+        * at a given index was already selected, it remains selected. Indices that\r
+        * are out of range and duplicate indices are ignored. If the receiver is\r
+        * single-select and multiple indices are specified, then all indices are\r
+        * ignored.\r
+        * \r
+        * @param indices the array of indices for the items to select\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the array of indices is null\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not\r
+        *                called from the thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void select(final int[] indices) {\r
+               this.checkWidget();\r
+               if (indices == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               for (final int index : indices) {\r
+                       if (index <= 0 || index >= this.items.size()) {\r
+                               continue;\r
+                       }\r
+                       this.selection.add(this.items.get(index));\r
+                       this.fireEvents(this.items.get(index));\r
+               }\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Selects the items in the range specified by the given zero-relative\r
+        * indices in the receiver. The range of indices is inclusive. The current\r
+        * selection is not cleared before the new items are selected.\r
+        * <p>\r
+        * If an item in the given range is not selected, it is selected. If an item\r
+        * in the given range was already selected, it remains selected. Indices\r
+        * that are out of range are ignored and no items will be selected if start\r
+        * is greater than end. If the receiver is single-select and there is more\r
+        * than one item in the given range, then all indices are ignored.\r
+        * \r
+        * @param start the start of the range\r
+        * @param end the end of the range\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not\r
+        *                called from the thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see List#setSelection(int,int)\r
+        */\r
+       public void select(final int start, final int end) {\r
+               this.checkWidget();\r
+               if (start > end) {\r
+                       SWT.error(SWT.ERROR_INVALID_RANGE);\r
+               }\r
+               for (int index = start; index <= end; index++) {\r
+                       if (index <= 0 || index >= this.items.size()) {\r
+                               continue;\r
+                       }\r
+                       this.selection.add(this.items.get(index));\r
+                       this.fireEvents(this.items.get(index));\r
+               }\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Selects all of the items in the receiver.\r
+        * <p>\r
+        * If the receiver is single-select, do nothing.\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not\r
+        *                called from the thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void selectAll() {\r
+               this.checkWidget();\r
+               this.selection.addAll(this.items);\r
+               for (final DLItem item : this.items) {\r
+                       this.fireEvents(item);\r
+               }\r
+               this.items.clear();\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#setBounds(int, int, int, int)\r
+        */\r
+       @Override\r
+       public void setBounds(final int x, final int y, final int width, final int height) {\r
+               super.setBounds(x, y, width, height);\r
+               final boolean itemsContainImage = this.itemsContainImage();\r
+               final Point itemsTableDefaultSize = this.itemsTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+               final Point selectionTableDefaultSize = this.selectionTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+\r
+               int itemsTableSize = this.itemsTable.getSize().x;\r
+               if (itemsTableDefaultSize.y > this.itemsTable.getSize().y) {\r
+                       itemsTableSize -= this.itemsTable.getVerticalBar().getSize().x;\r
+               }\r
+\r
+               int selectionTableSize = this.selectionTable.getSize().x;\r
+               if (selectionTableDefaultSize.y > this.selectionTable.getSize().y) {\r
+                       selectionTableSize -= this.selectionTable.getVerticalBar().getSize().x;\r
+               }\r
+\r
+               if (itemsContainImage) {\r
+                       this.itemsTable.getColumn(0).pack();\r
+                       this.itemsTable.getColumn(1).setWidth(itemsTableSize - this.itemsTable.getColumn(0).getWidth());\r
+\r
+                       this.selectionTable.getColumn(0).pack();\r
+                       this.selectionTable.getColumn(1).setWidth(selectionTableSize - this.selectionTable.getColumn(0).getWidth());\r
+\r
+               } else {\r
+                       this.itemsTable.getColumn(0).setWidth(itemsTableSize);\r
+                       this.selectionTable.getColumn(0).setWidth(selectionTableSize);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return <code>true</code> if any item contains an image\r
+        */\r
+       private boolean itemsContainImage() {\r
+               for (final DLItem item : this.items) {\r
+                       if (item.getImage() != null) {\r
+                               return true;\r
+                       }\r
+               }\r
+\r
+               for (final DLItem item : this.selection) {\r
+                       if (item.getImage() != null) {\r
+                               return true;\r
+                       }\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Sets the item in the receiver's list at the given zero-relative index to\r
+        * the item argument.\r
+        * \r
+        * @param index the index for the item\r
+        * @param item the new item\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the item is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setItem(final int index, final DLItem item) {\r
+               this.checkWidget();\r
+               if (item == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               if (index <= 0 || index >= this.items.size()) {\r
+                       SWT.error(SWT.ERROR_INVALID_RANGE);\r
+               }\r
+               this.items.set(index, item);\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's items to be the given array of items.\r
+        * \r
+        * @param items the array of items\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the items array is null</li>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if an item in the items array\r
+        *                is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setItems(final DLItem[] items) {\r
+               this.checkWidget();\r
+               if (items == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               final List<DLItem> temp = new ArrayList<DLItem>();\r
+               for (final DLItem item : items) {\r
+                       if (item == null) {\r
+                               SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+                       }\r
+                       temp.add(item);\r
+               }\r
+               this.items.clear();\r
+               this.items.addAll(temp);\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's items to be the given list of items.\r
+        * \r
+        * @param items the list of items\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the items list is null</li>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if an item in the items list\r
+        *                is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setItems(final List<DLItem> items) {\r
+               this.checkWidget();\r
+               this.checkWidget();\r
+               if (items == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               final List<DLItem> temp = new ArrayList<DLItem>();\r
+               for (final DLItem item : items) {\r
+                       if (item == null) {\r
+                               SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+                       }\r
+                       temp.add(item);\r
+               }\r
+               this.items.clear();\r
+               this.items.addAll(temp);\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Redraws all tables that compose this widget\r
+        */\r
+       private void redrawTables() {\r
+               this.setRedraw(false);\r
+               this.redrawTable(this.itemsTable, false);\r
+               this.redrawTable(this.selectionTable, true);\r
+               this.setRedraw(true);\r
+               this.setBounds(this.getBounds());\r
+       }\r
+\r
+       /**\r
+        * Redraw a given table\r
+        * \r
+        * @param table table to be redrawned\r
+        * @param isSelected if <code>true</code>, fill the table with the\r
+        *            selection. Otherwise, fill the table with the unselected\r
+        *            items.\r
+        */\r
+       private void redrawTable(final Table table, final boolean isSelected) {\r
+               this.clean(table);\r
+               this.fillData(table, isSelected ? this.selection : this.items);\r
+       }\r
+\r
+       /**\r
+        * Cleans the content of a table\r
+        * \r
+        * @param table table to be emptied\r
+        */\r
+       private void clean(final Table table) {\r
+               if (table == null) {\r
+                       return;\r
+               }\r
+\r
+               for (final TableItem item : table.getItems()) {\r
+                       item.dispose();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Fill a table with data\r
+        * \r
+        * @param table table to be filled\r
+        * @param listOfData list of data\r
+        */\r
+       private void fillData(final Table table, final List<DLItem> listOfData) {\r
+               for (final DLItem item : listOfData) {\r
+                       final TableItem tableItem = new TableItem(table, SWT.NONE);\r
+                       tableItem.setData(item);\r
+\r
+                       if (item.getBackground() != null) {\r
+                               tableItem.setBackground(item.getBackground());\r
+                       }\r
+\r
+                       if (item.getForeground() != null) {\r
+                               tableItem.setForeground(item.getForeground());\r
+                       }\r
+\r
+                       if (item.getImage() != null) {\r
+                               tableItem.setImage(0, item.getImage());\r
+                       }\r
+\r
+                       if (item.getFont() != null) {\r
+                               tableItem.setFont(item.getFont());\r
+                       }\r
+\r
+                       tableItem.setText(1, item.getText());\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Move the selected item to the first position\r
+        */\r
+       protected void moveSelectionToFirstPosition() {\r
+               if (this.selectionTable.getSelectionCount() == 0) {\r
+                       return;\r
+               }\r
+\r
+               int index = 0;\r
+               for (final TableItem tableItem : this.selectionTable.getSelection()) {\r
+                       final DLItem item = (DLItem) tableItem.getData();\r
+                       this.selection.remove(item);\r
+                       this.selection.add(index++, item);\r
+               }\r
+\r
+               this.redrawTables();\r
+               this.selectionTable.select(0, index - 1);\r
+               this.selectionTable.forceFocus();\r
+       }\r
+\r
+       /**\r
+        * Select a given item\r
+        */\r
+       protected void selectItem() {\r
+               if (this.itemsTable.getSelectionCount() == 0) {\r
+                       return;\r
+               }\r
+               for (final TableItem tableItem : this.itemsTable.getSelection()) {\r
+                       final DLItem item = (DLItem) tableItem.getData();\r
+                       this.selection.add(item);\r
+                       this.items.remove(item);\r
+               }\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Move the selected item up\r
+        */\r
+       protected void moveUpItem() {\r
+               if (this.selectionTable.getSelectionCount() == 0) {\r
+                       return;\r
+               }\r
+\r
+               for (final int index : this.selectionTable.getSelectionIndices()) {\r
+                       if (index == 0) {\r
+                               this.selectionTable.forceFocus();\r
+                               return;\r
+                       }\r
+               }\r
+\r
+               final int[] newSelection = new int[this.selectionTable.getSelectionCount()];\r
+               int newSelectionIndex = 0;\r
+               for (final TableItem tableItem : this.selectionTable.getSelection()) {\r
+                       final int position = this.selection.indexOf(tableItem.getData());\r
+                       this.swap(position, position - 1);\r
+                       newSelection[newSelectionIndex++] = position - 1;\r
+               }\r
+\r
+               this.redrawTables();\r
+               this.selectionTable.select(newSelection);\r
+               this.selectionTable.forceFocus();\r
+       }\r
+\r
+       /**\r
+        * Deselect a given item\r
+        */\r
+       protected void deselectItem() {\r
+               if (this.selectionTable.getSelectionCount() == 0) {\r
+                       return;\r
+               }\r
+               for (final TableItem tableItem : this.selectionTable.getSelection()) {\r
+                       final DLItem item = (DLItem) tableItem.getData();\r
+                       this.items.add(item);\r
+                       this.selection.remove(item);\r
+               }\r
+               this.redrawTables();\r
+       }\r
+\r
+       /**\r
+        * Move the selected item down\r
+        */\r
+       protected void moveDownItem() {\r
+               if (this.selectionTable.getSelectionCount() == 0) {\r
+                       return;\r
+               }\r
+\r
+               for (final int index : this.selectionTable.getSelectionIndices()) {\r
+                       if (index == this.selectionTable.getItemCount() - 1) {\r
+                               this.selectionTable.forceFocus();\r
+                               return;\r
+                       }\r
+               }\r
+\r
+               final int[] newSelection = new int[this.selectionTable.getSelectionCount()];\r
+               int newSelectionIndex = 0;\r
+               for (final TableItem tableItem : this.selectionTable.getSelection()) {\r
+                       final int position = this.selection.indexOf(tableItem.getData());\r
+                       this.swap(position, position + 1);\r
+                       newSelection[newSelectionIndex++] = position + 1;\r
+               }\r
+\r
+               this.redrawTables();\r
+               this.selectionTable.select(newSelection);\r
+               this.selectionTable.forceFocus();\r
+\r
+       }\r
+\r
+       /**\r
+        * Swap 2 items\r
+        * \r
+        * @param first position of the first item to swap\r
+        * @param second position of the second item to swap\r
+        */\r
+       private void swap(final int first, final int second) {\r
+               final DLItem temp = this.selection.get(first);\r
+               this.selection.set(first, this.selection.get(second));\r
+               this.selection.set(second, temp);\r
+       }\r
+\r
+       /**\r
+        * Move the selected item to the last position\r
+        */\r
+       protected void moveSelectionToLastPosition() {\r
+               if (this.selectionTable.getSelectionCount() == 0) {\r
+                       return;\r
+               }\r
+\r
+               final int numberOfSelectedElements = this.selectionTable.getSelectionCount();\r
+               for (final TableItem tableItem : this.selectionTable.getSelection()) {\r
+                       final DLItem item = (DLItem) tableItem.getData();\r
+                       this.selection.remove(item);\r
+                       this.selection.add(item);\r
+               }\r
+\r
+               this.redrawTables();\r
+               final int numberOfElements = this.selectionTable.getItemCount();\r
+               this.selectionTable.select(numberOfElements - numberOfSelectedElements, numberOfElements - 1);\r
+               this.selectionTable.forceFocus();\r
+       }\r
+\r
+       /**\r
+        * Call all selection listeners\r
+        * \r
+        * @param item selected item\r
+        */\r
+       private void fireEvents(final DLItem item) {\r
+               if (this.eventTable == null) {\r
+                       return;\r
+               }\r
+\r
+               final Event event = new Event();\r
+               event.button = 1;\r
+               event.display = this.getDisplay();\r
+               event.item = null;\r
+               event.widget = this;\r
+               event.data = item;\r
+               final SelectionEvent selectionEvent = new SelectionEvent(event);\r
+\r
+               for (final SelectionListener listener : this.eventTable) {\r
+                       listener.widgetSelected(selectionEvent);\r
+               }\r
+\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/launcher/LLabel.java b/org.tizen.common.externals/src/org/mihalis/opal/launcher/LLabel.java
new file mode 100644 (file)
index 0000000..d6aa5e5
--- /dev/null
@@ -0,0 +1,277 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.launcher;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instance of this class are a button with text, image and a nice animation\r
+ * effect\r
+ */\r
+class LLabel extends Canvas {\r
+\r
+       private String text;\r
+       private Image image;\r
+       private Font font;\r
+\r
+       private static final int GAP = 12;\r
+       private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER;\r
+       private static final int DEFAULT_MARGIN = 5;\r
+       private final int leftMargin = DEFAULT_MARGIN;\r
+       private final int topMargin = DEFAULT_MARGIN;\r
+       private final int rightMargin = DEFAULT_MARGIN;\r
+       private final int bottomMargin = DEFAULT_MARGIN;\r
+       private Point textSize;\r
+\r
+       private static final int MAX_NUMBER_OF_STEPS = 10;\r
+       private int animationStep = 0;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       LLabel(final Composite parent, final int style) {\r
+               super(parent, style | SWT.BORDER | SWT.DOUBLE_BUFFERED);\r
+\r
+               final Font original = super.getFont();\r
+\r
+               this.font = new Font(getDisplay(), original.getFontData()[0].getName(), 18, SWT.BOLD);\r
+\r
+               addPaintListener(new PaintListener() {\r
+                       @Override\r
+                       public void paintControl(final PaintEvent event) {\r
+                               onPaint(event);\r
+                       }\r
+               });\r
+\r
+               addListener(SWT.Dispose, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               onDispose(event);\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Draw the content of the LLabel\r
+        * \r
+        * @param event paintevent\r
+        */\r
+       private void onPaint(final PaintEvent event) {\r
+               final Rectangle rect = getClientArea();\r
+               if (rect.width == 0 || rect.height == 0) {\r
+                       return;\r
+               }\r
+\r
+               final Image bufferImage = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height));\r
+\r
+               final GC gc = new GC(bufferImage);\r
+               gc.setForeground(getForeground());\r
+               gc.setBackground(getBackground());\r
+\r
+               gc.fillRectangle(rect);\r
+\r
+               final Point extent = getTotalSize(this.image.getBounds().width, this.image.getBounds().height);\r
+               final int xImage = (rect.width - this.image.getBounds().width) / 2;\r
+               final int yImage = (rect.height - extent.y) / 2;\r
+               gc.drawImage(this.image, xImage, yImage);\r
+\r
+               gc.setFont(this.font);\r
+               final int xText = (rect.width - this.textSize.x) / 2;\r
+               final int yText = yImage + this.image.getBounds().height + GAP - this.textSize.y / 2;\r
+               gc.drawString(this.text, xText, yText);\r
+\r
+               if (this.animationStep != 0) {\r
+                       final float zoom = 1f + this.animationStep * (Math.max(extent.x, extent.y) - Math.max(this.image.getBounds().width, this.image.getBounds().height)) / MAX_NUMBER_OF_STEPS / 100f;\r
+\r
+                       final int newSizeX = (int) (this.image.getBounds().width * zoom);\r
+                       final int newSizeY = (int) (this.image.getBounds().height * zoom);\r
+\r
+                       gc.setAntialias(SWT.ON);\r
+                       gc.setInterpolation(SWT.HIGH);\r
+\r
+                       gc.setAlpha(255 - 255 / MAX_NUMBER_OF_STEPS * this.animationStep);\r
+\r
+                       final Point extentZoomedImage = getTotalSize(newSizeX, newSizeY);\r
+                       final int xZoomedImage = (rect.width - newSizeX) / 2;\r
+                       final int yZoomedImage = (rect.height - extentZoomedImage.y) / 2;\r
+                       gc.drawImage(this.image, 0, 0, this.image.getBounds().width, this.image.getBounds().height, xZoomedImage, yZoomedImage, (int) (this.image.getBounds().width * zoom), (int) (this.image.getBounds().height * zoom));\r
+\r
+               }\r
+\r
+               gc.dispose();\r
+\r
+               event.gc.drawImage(bufferImage, 0, 0);\r
+\r
+               bufferImage.dispose();\r
+\r
+       }\r
+\r
+       /**\r
+        * Dispose elements when the widget is disposed\r
+        * \r
+        * @param event dispose event\r
+        */\r
+       private void onDispose(final Event event) {\r
+               SWTGraphicUtil.dispose(this.image);\r
+               SWTGraphicUtil.dispose(this.font);\r
+               this.text = null;\r
+               this.image = null;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)\r
+        */\r
+       @Override\r
+       public Point computeSize(final int wHint, final int hHint, final boolean changed) {\r
+               checkWidget();\r
+               final Point e = getTotalSize(this.image.getBounds().width, this.image.getBounds().height);\r
+               if (wHint == SWT.DEFAULT) {\r
+                       e.x += this.leftMargin + this.rightMargin;\r
+               } else {\r
+                       e.x = wHint;\r
+               }\r
+               if (hHint == SWT.DEFAULT) {\r
+                       e.y += this.topMargin + this.bottomMargin;\r
+               } else {\r
+                       e.y = hHint;\r
+               }\r
+               return e;\r
+       }\r
+\r
+       /**\r
+        * Compute the size of the content (image + text + gap)\r
+        * \r
+        * @param imgWidth image width\r
+        * @param imgHeight image height\r
+        * @return the size of the content\r
+        */\r
+       private Point getTotalSize(final int imgWidth, final int imgHeight) {\r
+               final Point size = new Point(0, 0);\r
+\r
+               int textWidth = 0;\r
+               int textHeight = 0;\r
+\r
+               if (this.textSize == null) {\r
+                       final GC gc = new GC(this);\r
+                       gc.setFont(this.font);\r
+\r
+                       this.textSize = gc.textExtent(this.text, DRAW_FLAGS);\r
+                       gc.dispose();\r
+\r
+               }\r
+               textWidth = this.textSize.x;\r
+               textHeight = this.textSize.y;\r
+\r
+               size.x = Math.max(imgWidth, textWidth);\r
+               size.y = imgHeight + GAP + textHeight;\r
+\r
+               return size;\r
+       }\r
+\r
+       /**\r
+        * @return the text\r
+        */\r
+       String getText() {\r
+               return this.text;\r
+       }\r
+\r
+       /**\r
+        * @param text the text to set\r
+        */\r
+       void setText(final String text) {\r
+               this.text = text;\r
+       }\r
+\r
+       /**\r
+        * @return the image\r
+        */\r
+       Image getImage() {\r
+               return this.image;\r
+       }\r
+\r
+       /**\r
+        * @param image the image to set\r
+        */\r
+       void setImage(final Image image) {\r
+               this.image = image;\r
+       }\r
+\r
+       /**\r
+        * @return the font\r
+        */\r
+       @Override\r
+       public Font getFont() {\r
+               return this.font;\r
+       }\r
+\r
+       /**\r
+        * @param font the font to set\r
+        */\r
+       @Override\r
+       public void setFont(final Font font) {\r
+               SWTGraphicUtil.dispose(font);\r
+               this.font = font;\r
+       }\r
+\r
+       /**\r
+        * Increment the steps of the animation\r
+        * \r
+        * @return true if animation keeps running, false otherwise\r
+        */\r
+       boolean incrementAnimation() {\r
+               this.animationStep++;\r
+               final boolean stopAnimation = this.animationStep > MAX_NUMBER_OF_STEPS;\r
+\r
+               if (stopAnimation) {\r
+                       this.animationStep = 0;\r
+               }\r
+               if (!isDisposed()) {\r
+                       redraw();\r
+               }\r
+               return !stopAnimation;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/launcher/Launcher.java b/org.tizen.common.externals/src/org/mihalis/opal/launcher/Launcher.java
new file mode 100755 (executable)
index 0000000..42bf7b1
--- /dev/null
@@ -0,0 +1,428 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.launcher;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are a launcher composed of buttons. When one clicks\r
+ * on the button, an animation is started and a selection event is fired\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>Selection</dd>\r
+ * </dl>\r
+ */\r
+public class Launcher extends Composite {\r
+\r
+       private final List<LauncherItem> items;\r
+       private final List<SelectionListener> selectionListeners;\r
+       private boolean needRedraw;\r
+       private int selection = -1;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       public Launcher(final Composite parent, final int style) {\r
+               super(parent, style | SWT.BORDER);\r
+               this.items = new ArrayList<LauncherItem>();\r
+               this.selectionListeners = new ArrayList<SelectionListener>();\r
+               this.needRedraw = true;\r
+               setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+\r
+               this.addListener(SWT.Resize, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               drawLauncher();\r
+                       }\r
+               });\r
+\r
+               this.addListener(SWT.KeyUp, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               OnKeyPressed(event);\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Draw the launcher\r
+        */\r
+       private void drawLauncher() {\r
+               if (!this.needRedraw) {\r
+                       return;\r
+               }\r
+\r
+               disposePreviousContent();\r
+               createButtons();\r
+               pack();\r
+\r
+               this.needRedraw = false;\r
+       }\r
+\r
+       /**\r
+        * Dispose the content before a redraw\r
+        */\r
+       private void disposePreviousContent() {\r
+               for (final Control c : this.getChildren()) {\r
+                       c.dispose();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Create the buttons that will compose the launcher\r
+        */\r
+       private void createButtons() {\r
+               final GridLayout gridLayout = new GridLayout(this.items.size() / 2, true);\r
+               gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;\r
+               this.setLayout(gridLayout);\r
+               for (final LauncherItem item : this.items) {\r
+                       final LLabel label = new LLabel(this, SWT.CENTER);\r
+                       label.setText(item.title);\r
+                       label.setImage(SWTGraphicUtil.createImage(item.image));\r
+                       label.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+                       final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false);\r
+                       gd.widthHint = 192;\r
+                       gd.heightHint = 220;\r
+                       label.setLayoutData(gd);\r
+                       item.label = label;\r
+\r
+                       label.addListener(SWT.KeyUp, new Listener() {\r
+\r
+                               @Override\r
+                               public void handleEvent(final Event event) {\r
+                                       OnKeyPressed(event);\r
+                               }\r
+                       });\r
+\r
+                       label.addListener(SWT.MouseUp, new Listener() {\r
+\r
+                               @Override\r
+                               public void handleEvent(final Event event) {\r
+                                       OnClick(event);\r
+                               }\r
+                       });\r
+\r
+                       label.addListener(SWT.MouseDoubleClick, new Listener() {\r
+\r
+                               @Override\r
+                               public void handleEvent(final Event event) {\r
+                                       OnDoubleClick(event);\r
+                               }\r
+                       });\r
+\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Code executed when a key is pressed\r
+        * \r
+        * @param event Event\r
+        */\r
+       private void OnKeyPressed(final Event event) {\r
+               switch (event.keyCode) {\r
+               case SWT.ARROW_LEFT:\r
+                       if (this.selection == -1) {\r
+                               this.selection = 0;\r
+                               changeColor(this.selection, true);\r
+                               return;\r
+                       }\r
+\r
+                       if (this.selection % 2 == 1) {\r
+                               changeColor(this.selection, false);\r
+                               this.selection--;\r
+                               changeColor(this.selection, true);\r
+                       }\r
+                       break;\r
+               case SWT.ARROW_UP:\r
+                       if (this.selection == -1) {\r
+                               this.selection = 0;\r
+                               changeColor(this.selection, true);\r
+                               return;\r
+                       }\r
+                       if (this.selection >= 2) {\r
+                               changeColor(this.selection, false);\r
+                               this.selection -= 2;\r
+                               changeColor(this.selection, true);\r
+                       }\r
+                       break;\r
+               case SWT.ARROW_RIGHT:\r
+                       if (this.selection == -1) {\r
+                               this.selection = 0;\r
+                               changeColor(this.selection, true);\r
+                               return;\r
+                       }\r
+                       if (this.selection % 2 == 0) {\r
+                               changeColor(this.selection, false);\r
+                               this.selection++;\r
+                               changeColor(this.selection, true);\r
+                       }\r
+                       break;\r
+               case SWT.ARROW_DOWN:\r
+                       if (this.selection == -1) {\r
+                               this.selection = 0;\r
+                               changeColor(this.selection, true);\r
+                               return;\r
+                       }\r
+                       if (this.selection <= this.items.size() - 2) {\r
+                               changeColor(this.selection, false);\r
+                               this.selection += 2;\r
+                               changeColor(this.selection, true);\r
+                       }\r
+                       break;\r
+               case SWT.HOME:\r
+                       changeColor(this.selection, false);\r
+                       this.selection = 0;\r
+                       changeColor(this.selection, true);\r
+                       break;\r
+               case SWT.END:\r
+                       changeColor(this.selection, false);\r
+                       this.selection = this.items.size() - 1;\r
+                       changeColor(this.selection, true);\r
+                       break;\r
+               default:\r
+                        break;   \r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Code executed when one clicks on the button\r
+        * \r
+        * @param event Event\r
+        */\r
+       private void OnClick(final Event event) {\r
+               for (int i = 0; i < this.items.size(); i++) {\r
+                       final LauncherItem item = this.items.get(i);\r
+                       if (item.label != null && item.label.equals(event.widget)) {\r
+                               if (this.selection != i) {\r
+                                       changeColor(this.selection, false);\r
+                                       this.selection = i;\r
+                                       changeColor(this.selection, true);\r
+                               }\r
+                               return;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Change the background color of a given button\r
+        * \r
+        * @param index index of the button\r
+        * @param isSelected if <code>true</code>, the background is the light\r
+        *            shadow. Otherwise, the background color is white\r
+        */\r
+       private void changeColor(final int index, final boolean isSelected) {\r
+               if (index != -1 && this.items.get(index).label != null) {\r
+                       this.items.get(index).label.setBackground(isSelected ? getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW) : getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Code executed when one double-clicks on a button\r
+        * \r
+        * @param event Event\r
+        */\r
+       private void OnDoubleClick(final Event event) {\r
+               for (int i = 0; i < this.items.size(); i++) {\r
+                       final LauncherItem item = this.items.get(i);\r
+                       if (item.label != null && item.label.equals(event.widget)) {\r
+                               if (this.selection != i) {\r
+                                       changeColor(this.selection, false);\r
+                                       this.selection = i;\r
+                                       changeColor(this.selection, true);\r
+                               }\r
+                               startAnimation(i, event);\r
+                               return;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Start the animation for a given button\r
+        * \r
+        * @param index index of the selected button\r
+        * @param event event (propagated to the selection listeners)\r
+        */\r
+       private void startAnimation(final int index, final Event event) {\r
+               final LLabel label = this.items.get(index).label;\r
+               getDisplay().timerExec(0, new Runnable() {\r
+\r
+                       @Override\r
+                       public void run() {\r
+                               if (label.incrementAnimation()) {\r
+                                       getDisplay().timerExec(20, this);\r
+                               } else {\r
+                                       fireSelectionListeners(event);\r
+                               }\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Fire the selection listeners\r
+        * \r
+        * @param originalEvent mouse event\r
+        * @return <code>true</code> if the selection could be changed,\r
+        *         <code>false</code> otherwise\r
+        */\r
+       private boolean fireSelectionListeners(final Event originalEvent) {\r
+               for (final SelectionListener listener : this.selectionListeners) {\r
+                       final Event event = new Event();\r
+\r
+                       event.button = originalEvent.button;\r
+                       event.display = this.getDisplay();\r
+                       event.item = null;\r
+                       event.widget = this;\r
+                       event.data = null;\r
+                       event.time = originalEvent.time;\r
+                       event.x = originalEvent.x;\r
+                       event.y = originalEvent.y;\r
+\r
+                       final SelectionEvent selEvent = new SelectionEvent(event);\r
+                       listener.widgetSelected(selEvent);\r
+                       if (!selEvent.doit) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Add an item to the launcher\r
+        * \r
+        * @param title text associated to this item\r
+        * @param image image associated to this item\r
+        */\r
+       public void addItem(final String title, final String image) {\r
+               checkWidget();\r
+               this.items.add(new LauncherItem(title, image));\r
+               this.needRedraw = true;\r
+       }\r
+\r
+       /**\r
+        * Adds the listener to the collection of listeners who will be notified\r
+        * when the control is selected by the user, by sending it one of the\r
+        * messages defined in the <code>SelectionListener</code> interface.\r
+        * <p>\r
+        * <code>widgetSelected</code> is called when the control is selected by the\r
+        * user. <code>widgetDefaultSelected</code> is not called.\r
+        * </p>\r
+        * \r
+        * @param listener the listener which should be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #removeSelectionListener\r
+        * @see SelectionEvent\r
+        */\r
+       public void addSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               if (listener == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               this.selectionListeners.add(listener);\r
+\r
+       }\r
+\r
+       /**\r
+        * Removes the listener from the collection of listeners who will be\r
+        * notified when the control is selected by the user.\r
+        * \r
+        * @param listener the listener which should no longer be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #addSelectionListener\r
+        */\r
+       public void removeSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               if (listener == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               this.selectionListeners.remove(listener);\r
+       }\r
+\r
+       /**\r
+        * Return the selected button\r
+        * \r
+        * @return the index of the selected button\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       public int getSelection() {\r
+               checkWidget();\r
+               return this.selection;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/launcher/LauncherItem.java b/org.tizen.common.externals/src/org/mihalis/opal/launcher/LauncherItem.java
new file mode 100644 (file)
index 0000000..bb5dc13
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.launcher;\r
+\r
+/**\r
+ * Instances of this class are POJO to store information handled by the Launcher\r
+ * widget I could have used a inner class but I prefer this solution :)\r
+ */\r
+class LauncherItem {\r
+       String title;\r
+       String image;\r
+       LLabel label;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param title text associated to the item\r
+        * @param image image associated to the item\r
+        */\r
+       LauncherItem(final String title, final String image) {\r
+               this.title = title;\r
+               this.image = image;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialog.java b/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialog.java
new file mode 100644 (file)
index 0000000..b811971
--- /dev/null
@@ -0,0 +1,511 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation \r
+ *******************************************************************************/\r
+package org.mihalis.opal.login;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Path;\r
+import org.eclipse.swt.graphics.Pattern;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.mihalis.opal.opalDialog.Dialog;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are Login Dialog box, which is composed of\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>A login</b></dt>\r
+ * <dt><b>A password</b></dt>\r
+ * <dt><b>An image</b></dt>\r
+ * <dd>(optional)</dd>\r
+ * <dt><b>A description</b></dt>\r
+ * <dd>(optional)</dd>\r
+ * <dt><b>A checkbox "remember the password"</b></dt>\r
+ * <dd>(optional)</dd>\r
+ * </dl>\r
+ * </p>\r
+ */\r
+public class LoginDialog {\r
+       private Image image;\r
+       private String description;\r
+       private String login;\r
+       private String password;\r
+       private List<String> autorizedLogin;\r
+       private boolean displayRememberPassword;\r
+       private boolean rememberPassword;\r
+       private LoginDialogVerifier verifier;\r
+\r
+       private Shell shell;\r
+       private boolean returnedValue;\r
+       private Button buttonOk;\r
+\r
+       /**\r
+        * Constructor\r
+        */\r
+       public LoginDialog() {\r
+               this.displayRememberPassword = true;\r
+       }\r
+\r
+       /**\r
+        * Open the Login box\r
+        * \r
+        * @return <code>true</code> if the authentication is OK, <code>false</code>\r
+        *         if the user pressed on cancel.\r
+        */\r
+       public boolean open() {\r
+               if (this.verifier == null) {\r
+                       throw new IllegalArgumentException("Please set a verifier before opening the dialog box");\r
+               }\r
+\r
+               buildDialog();\r
+               openShell();\r
+\r
+               return this.returnedValue;\r
+       }\r
+\r
+       /**\r
+        * Build the dialog box\r
+        */\r
+       private void buildDialog() {\r
+               buildShell();\r
+               buildImage();\r
+               buildDescription();\r
+               buildLogin();\r
+               buildPassword();\r
+               if (this.displayRememberPassword) {\r
+                       buildRememberPassword();\r
+               }\r
+               buildButtons();\r
+       }\r
+\r
+       /**\r
+        * Build the shell\r
+        */\r
+       private void buildShell() {\r
+               this.shell = new Shell(SWT.SYSTEM_MODAL | SWT.TITLE | SWT.BORDER);\r
+               this.shell.setText(ResourceManager.getLabel(ResourceManager.LOGIN));\r
+               this.shell.setLayout(new GridLayout(4, false));\r
+       }\r
+\r
+       /**\r
+        * Build the image on top of the login box. If no image has been set, create\r
+        * a default image\r
+        */\r
+       private void buildImage() {\r
+               final Canvas canvas = new Canvas(this.shell, SWT.DOUBLE_BUFFERED);\r
+               final GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, false, 4, 1);\r
+               gridData.widthHint = 400;\r
+               gridData.heightHint = 60;\r
+               canvas.setLayoutData(gridData);\r
+               canvas.addPaintListener(new PaintListener() {\r
+\r
+                       @Override\r
+                       public void paintControl(final PaintEvent e) {\r
+                               e.gc.drawImage(LoginDialog.this.image == null ? createDefaultImage(e.width, e.height) : LoginDialog.this.image, 0, 0);\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Create a default image. It is a port of the image used by the Login Box\r
+        * in the project SwingX\r
+        * \r
+        * @param w width\r
+        * @param h height\r
+        * @return a default image (blue wave)\r
+        */\r
+       private Image createDefaultImage(final int w, final int h) {\r
+               final Display display = Display.getCurrent();\r
+               final Color backgroundColor = new Color(display, 49, 121, 242);\r
+               final Color gradientColor1 = new Color(display, 155, 185, 245);\r
+               final Color gradientColor2 = new Color(display, 53, 123, 242);\r
+\r
+               final Image img = new Image(display, w, h);\r
+               final GC gc = new GC(img);\r
+               gc.setAdvanced(true);\r
+               gc.setAntialias(SWT.ON);\r
+               gc.setBackground(backgroundColor);\r
+               gc.fillRectangle(0, 0, w, h);\r
+\r
+               final Path curveShape = new Path(display);\r
+               curveShape.moveTo(0, h * .6f);\r
+               curveShape.cubicTo(w * .167f, h * 1.2f, w * .667f, h * -.5f, w, h * .75f);\r
+               curveShape.lineTo(w, h);\r
+               curveShape.lineTo(0, h);\r
+               curveShape.lineTo(0, h * .8f);\r
+               curveShape.close();\r
+\r
+               final Pattern pattern = new Pattern(display, 0, 0, 1, h * 1.2f, gradientColor1, gradientColor2);\r
+               gc.setBackgroundPattern(pattern);\r
+               gc.fillPath(curveShape);\r
+\r
+               final Font font = new Font(display, "Arial Bold", 30, SWT.NONE);\r
+               gc.setFont(font);\r
+               gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));\r
+               final Point textSize = gc.stringExtent(ResourceManager.getLabel(ResourceManager.LOGIN));\r
+               gc.drawString(ResourceManager.getLabel(ResourceManager.LOGIN), (int) (w * .05f), (h - textSize.y) / 2, true);\r
+\r
+               font.dispose();\r
+               curveShape.dispose();\r
+               pattern.dispose();\r
+               backgroundColor.dispose();\r
+               gradientColor1.dispose();\r
+               gradientColor2.dispose();\r
+               gc.dispose();\r
+               return img;\r
+       }\r
+\r
+       /**\r
+        * Build the description part of the box\r
+        */\r
+       private void buildDescription() {\r
+               final Label label = new Label(this.shell, SWT.NONE);\r
+               final GridData gridData = new GridData(GridData.FILL, GridData.BEGINNING, true, false, 4, 1);\r
+               gridData.verticalIndent = 5;\r
+               gridData.horizontalIndent = 5;\r
+               label.setLayoutData(gridData);\r
+               final Font bold = SWTGraphicUtil.buildFontFrom(label, SWT.BOLD);\r
+               label.setFont(bold);\r
+               label.addListener(SWT.Dispose, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               SWTGraphicUtil.dispose(bold);\r
+                       }\r
+               });\r
+\r
+               if (this.description == null || this.description.trim().equals("")) {\r
+                       label.setText(" ");\r
+               } else {\r
+                       label.setText(this.description);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Build the login part of the box\r
+        */\r
+       private void buildLogin() {\r
+               final Label label = new Label(this.shell, SWT.NONE);\r
+               final GridData gridData = new GridData(GridData.END, GridData.END, false, false, 1, 1);\r
+               gridData.horizontalIndent = 35;\r
+               gridData.verticalIndent = 15;\r
+               label.setLayoutData(gridData);\r
+               label.setText(ResourceManager.getLabel(ResourceManager.NAME));\r
+\r
+               if (this.autorizedLogin != null && !this.autorizedLogin.isEmpty()) {\r
+                       // Combo\r
+                       final Combo combo = new Combo(this.shell, SWT.BORDER | SWT.READ_ONLY);\r
+\r
+                       combo.setLayoutData(new GridData(GridData.FILL, GridData.END, true, false, 3, 1));\r
+                       for (final String loginToAdd : this.autorizedLogin) {\r
+                               combo.add(loginToAdd);\r
+                       }\r
+                       combo.setText(this.login == null ? "" : this.login);\r
+                       combo.setFocus();\r
+                       combo.addModifyListener(new ModifyListener() {\r
+\r
+                               @Override\r
+                               public void modifyText(final ModifyEvent e) {\r
+                                       LoginDialog.this.login = combo.getText();\r
+                                       changeButtonOkState();\r
+                               }\r
+                       });\r
+               } else {\r
+                       // Text\r
+                       final Text text = new Text(this.shell, SWT.BORDER);\r
+                       text.setText(this.login == null ? "" : this.login);\r
+                       text.setLayoutData(new GridData(GridData.FILL, GridData.END, true, false, 3, 1));\r
+                       text.setFocus();\r
+                       text.addModifyListener(new ModifyListener() {\r
+\r
+                               @Override\r
+                               public void modifyText(final ModifyEvent e) {\r
+                                       LoginDialog.this.login = text.getText();\r
+                                       changeButtonOkState();\r
+                               }\r
+                       });\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Build the password part of the box\r
+        */\r
+       private void buildPassword() {\r
+               final Label label = new Label(this.shell, SWT.NONE);\r
+               final GridData gridData = new GridData(GridData.END, GridData.CENTER, false, false, 1, 1);\r
+               gridData.horizontalIndent = 35;\r
+               label.setLayoutData(gridData);\r
+               label.setText(ResourceManager.getLabel(ResourceManager.PASSWORD));\r
+\r
+               final Text text = new Text(this.shell, SWT.PASSWORD | SWT.BORDER);\r
+               text.setText(this.password == null ? "" : this.password);\r
+               text.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1));\r
+               text.addModifyListener(new ModifyListener() {\r
+\r
+                       @Override\r
+                       public void modifyText(final ModifyEvent e) {\r
+                               LoginDialog.this.password = text.getText();\r
+                               changeButtonOkState();\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Enable/Disable the button when the login and the password is empty (or\r
+        * not)\r
+        */\r
+       private void changeButtonOkState() {\r
+               final boolean loginEntered = this.login != null && !this.login.trim().equals("");\r
+               final boolean passwordEntered = this.password != null && !this.password.trim().equals("");\r
+               this.buttonOk.setEnabled(loginEntered && passwordEntered);\r
+\r
+       }\r
+\r
+       /**\r
+        * Build the "remember password" part of the box\r
+        */\r
+       private void buildRememberPassword() {\r
+               final Button checkbox = new Button(this.shell, SWT.CHECK);\r
+               final GridData gridData = new GridData(GridData.BEGINNING, GridData.CENTER, true, false, 4, 1);\r
+               gridData.horizontalIndent = 35;\r
+               checkbox.setLayoutData(gridData);\r
+               checkbox.setText(ResourceManager.getLabel(ResourceManager.REMEMBER_PASSWORD));\r
+               checkbox.setSelection(this.rememberPassword);\r
+\r
+       }\r
+\r
+       /**\r
+        * Build the buttons\r
+        */\r
+       private void buildButtons() {\r
+               this.buttonOk = new Button(this.shell, SWT.PUSH);\r
+               final GridData gdOk = new GridData(GridData.END, GridData.CENTER, true, false, 3, 1);\r
+               gdOk.verticalIndent = 60;\r
+               gdOk.minimumWidth = 80;\r
+               this.buttonOk.setLayoutData(gdOk);\r
+               this.buttonOk.setText(ResourceManager.getLabel(ResourceManager.OK));\r
+               this.buttonOk.setEnabled(false);\r
+\r
+               this.buttonOk.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent selectionEvent) {\r
+                               try {\r
+                                       LoginDialog.this.verifier.authenticate(LoginDialog.this.login, LoginDialog.this.password);\r
+                                       LoginDialog.this.returnedValue = true;\r
+                                       LoginDialog.this.shell.dispose();\r
+                               } catch (final Exception e) {\r
+                                       Dialog.error(ResourceManager.getLabel(ResourceManager.LOGIN_FAILED), e.getMessage());\r
+                                       for (final Control control : LoginDialog.this.shell.getChildren()) {\r
+                                               if (control instanceof Text || control instanceof Combo) {\r
+                                                       control.setFocus();\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+\r
+                               }\r
+                       }\r
+\r
+               });\r
+\r
+               final Button buttonCancel = new Button(this.shell, SWT.PUSH);\r
+               final GridData gdCancel = new GridData(GridData.FILL, GridData.CENTER, false, false);\r
+               gdCancel.widthHint = 80;\r
+               gdCancel.verticalIndent = 60;\r
+               buttonCancel.setLayoutData(gdCancel);\r
+               buttonCancel.setText(ResourceManager.getLabel(ResourceManager.CANCEL));\r
+               buttonCancel.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               LoginDialog.this.returnedValue = false;\r
+                               LoginDialog.this.shell.dispose();\r
+                       }\r
+\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Open the shell\r
+        */\r
+       private void openShell() {\r
+               this.shell.setDefaultButton(this.buttonOk);\r
+               this.shell.pack();\r
+               this.shell.open();\r
+               SWTGraphicUtil.centerShell(this.shell);\r
+\r
+               while (!this.shell.isDisposed()) {\r
+                       if (!this.shell.getDisplay().readAndDispatch()) {\r
+                               this.shell.getDisplay().sleep();\r
+                       }\r
+               }\r
+       }\r
+\r
+       // ------------- Getters & Setters\r
+       /**\r
+        * @return the image\r
+        */\r
+       public Image getImage() {\r
+               return this.image;\r
+       }\r
+\r
+       /**\r
+        * @return the description\r
+        */\r
+       public String getDescription() {\r
+               return this.description;\r
+       }\r
+\r
+       /**\r
+        * @return the login\r
+        */\r
+       public String getLogin() {\r
+               return this.login == null ? null : this.login.trim();\r
+       }\r
+\r
+       /**\r
+        * @return the password\r
+        */\r
+       public String getPassword() {\r
+               return this.password == null ? null : this.password.trim();\r
+       }\r
+\r
+       /**\r
+        * @return the list of autorized logins\r
+        */\r
+       public List<String> getAutorizedLogin() {\r
+               return this.autorizedLogin;\r
+       }\r
+\r
+       /**\r
+        * @return <code>true</code> if the checkbox "remember the password" is\r
+        *         displayed, <code>false</code> otherwise\r
+        */\r
+       public boolean isDisplayRememberPassword() {\r
+               return this.displayRememberPassword;\r
+       }\r
+\r
+       /**\r
+        * @return <code>true</code> if the checkbox "remember the password" is\r
+        *         checked, <code>false</code> otherwise\r
+        */\r
+       public boolean isRememberPassword() {\r
+               return this.rememberPassword;\r
+       }\r
+\r
+       /**\r
+        * @return the verifier associated to this box\r
+        */\r
+       public LoginDialogVerifier getVerifier() {\r
+               return this.verifier;\r
+       }\r
+\r
+       /**\r
+        * @param image the image to set\r
+        */\r
+       public void setImage(final Image image) {\r
+               this.image = image;\r
+       }\r
+\r
+       /**\r
+        * @param description the description to set\r
+        */\r
+       public void setDescription(final String description) {\r
+               this.description = description;\r
+       }\r
+\r
+       /**\r
+        * @param login the login to set\r
+        */\r
+       public void setLogin(final String login) {\r
+               this.login = login;\r
+       }\r
+\r
+       /**\r
+        * @param password the password to set\r
+        */\r
+       public void setPassword(final String password) {\r
+               this.password = password;\r
+       }\r
+\r
+       /**\r
+        * @param autorizedLogin the list of autorized logins to set\r
+        */\r
+       public void setAutorizedLogin(final List<String> autorizedLogin) {\r
+               this.autorizedLogin = autorizedLogin;\r
+       }\r
+\r
+       /**\r
+        * @param autorizedLogin the list of autorized logins to set\r
+        */\r
+       public void setAutorizedLogin(final String... autorizedLogin) {\r
+               this.autorizedLogin = Arrays.asList(autorizedLogin);\r
+       }\r
+\r
+       /**\r
+        * @param displayRememberPassword if <code>true</code>, the checkbox\r
+        *            "remember the password" is displayed\r
+        */\r
+       public void setDisplayRememberPassword(final boolean displayRememberPassword) {\r
+               this.displayRememberPassword = displayRememberPassword;\r
+       }\r
+\r
+       /**\r
+        * @param rememberPassword if <code>true</code>, the checkbox\r
+        *            "remember the password" is selected\r
+        */\r
+       public void setRememberPassword(final boolean rememberPassword) {\r
+               this.rememberPassword = rememberPassword;\r
+       }\r
+\r
+       /**\r
+        * @param verifier the verifier to set\r
+        */\r
+       public void setVerifier(final LoginDialogVerifier verifier) {\r
+               this.verifier = verifier;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialogVerifier.java b/org.tizen.common.externals/src/org/mihalis/opal/login/LoginDialogVerifier.java
new file mode 100644 (file)
index 0000000..14ec22c
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation \r
+ *******************************************************************************/\r
+package org.mihalis.opal.login;\r
+\r
+/**\r
+ * This interface describes a verifier for the LoginDialogWidget\r
+ */\r
+public interface LoginDialogVerifier {\r
+       /**\r
+        * Check if the couple login/password is correct\r
+        * \r
+        * @param login login entered by the user\r
+        * @param password password entered by the user\r
+        * @throws Exception if the couple login/password is wrong. The description\r
+        *             of the exception contains the error message that is gonna be\r
+        *             displayed. For instance, an implementation can throw the\r
+        *             exception *\r
+        *             <code>new Exception("Unable to connect to the LDAP Server")</code>\r
+        */\r
+       void authenticate(String login, String password) throws Exception;\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoice.java b/org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoice.java
new file mode 100755 (executable)
index 0000000..3a5cb0e
--- /dev/null
@@ -0,0 +1,1195 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.mihalis.opal.multiChoice;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.LinkedHashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.mihalis.opal.utils.SimpleSelectionAdapter;\r
+\r
+/**\r
+ * The MultiChoice class represents a selectable user interface object that\r
+ * combines a read-only text-field and a set of checkboxes.\r
+ * \r
+ * <p>\r
+ * Note that although this class is a subclass of <code>Composite</code>, it\r
+ * does not make sense to add children to it, or set a layout on it.\r
+ * </p>\r
+ * <dl>\r
+ * <dt><b>Styles:</b>\r
+ * <dd>NONE</dd>\r
+ * <dt><b>Events:</b>\r
+ * <dd>Selection</dd>\r
+ * </dl>\r
+ * \r
+ * @param <T> Class of objects represented by this widget\r
+ */\r
+public class MultiChoice<T> extends Composite {\r
+\r
+       private Label text;\r
+       private Button arrow;\r
+       private Shell popup;\r
+       private Listener listener, filter;\r
+       private int numberOfColumns = 2;\r
+       private List<T> elements;\r
+       private Set<T> selection;\r
+       private List<Button> checkboxes;\r
+       private boolean hasFocus;\r
+       private MultiChoiceSelectionListener<T> selectionListener;\r
+       private T lastModified;\r
+       private Color foreground, background;\r
+       private Font font;\r
+       private String separator;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent.\r
+        * \r
+        * @param parent a widget which will be the parent of the new instance\r
+        *            (cannot be null)\r
+        * @param style not used\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        */\r
+       public MultiChoice(final Composite parent, final int style) {\r
+               this(parent, style, null);\r
+       }\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent.\r
+        * \r
+        * @param parent a widget which will be the parent of the new instance\r
+        *            (cannot be null)\r
+        * @param style not used\r
+        * @param elements list of elements displayed by this widget\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        */\r
+       public MultiChoice(final Composite parent, final int style, final List<T> elements) {\r
+               super(parent, style);\r
+\r
+               final GridLayout gridLayout = new GridLayout(2, false);\r
+               gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginWidth = gridLayout.marginHeight = 0;\r
+               this.setLayout(gridLayout);\r
+\r
+               this.text = new Label(this, SWT.SINGLE | SWT.READ_ONLY | SWT.BORDER);\r
+               this.text.setBackground(this.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));\r
+               this.text.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));\r
+\r
+               this.arrow = new Button(this, SWT.ARROW | SWT.RIGHT);\r
+               this.arrow.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false));\r
+\r
+               this.listener = new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               if (MultiChoice.this.popup == event.widget) {\r
+                                       popupEvent(event);\r
+                                       return;\r
+                               }\r
+\r
+                               if (MultiChoice.this.arrow == event.widget) {\r
+                                       buttonEvent(event);\r
+                                       return;\r
+                               }\r
+\r
+                               if (MultiChoice.this == event.widget) {\r
+                                       multiChoiceEvent(event);\r
+                                       return;\r
+                               }\r
+\r
+                               if (getShell() == event.widget) {\r
+                                       getDisplay().asyncExec(new Runnable() {\r
+                                               @Override\r
+                                               public void run() {\r
+                                                       if (isDisposed()) {\r
+                                                               return;\r
+                                                       }\r
+                                                       handleFocus(SWT.FocusOut);\r
+                                               }\r
+                                       });\r
+                               }\r
+                       }\r
+               };\r
+\r
+               final int[] multiChoiceEvent = { SWT.Dispose, SWT.Move, SWT.Resize };\r
+               for (int i = 0; i < multiChoiceEvent.length; i++) {\r
+                       this.addListener(multiChoiceEvent[i], this.listener);\r
+               }\r
+\r
+               final int[] buttonEvents = { SWT.Selection, SWT.FocusIn };\r
+               for (int i = 0; i < buttonEvents.length; i++) {\r
+                       this.arrow.addListener(buttonEvents[i], this.listener);\r
+               }\r
+\r
+               this.filter = new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final Shell shell = ((Control) event.widget).getShell();\r
+                               if (shell == MultiChoice.this.getShell()) {\r
+                                       handleFocus(SWT.FocusOut);\r
+                               }\r
+                       }\r
+               };\r
+\r
+               this.selection = new LinkedHashSet<T>();\r
+               this.elements = elements;\r
+               this.separator = ",";\r
+\r
+               createPopup();\r
+               setLabel();\r
+       }\r
+\r
+       /**\r
+        * Adds the argument to the end of the receiver's list.\r
+        * \r
+        * @param values new item\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void add(final T value) {\r
+               checkWidget();\r
+               if (value == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.elements == null) {\r
+                       this.elements = new ArrayList<T>();\r
+               }\r
+               this.elements.add(value);\r
+               refresh();\r
+       }\r
+\r
+       /**\r
+        * Adds the argument to the receiver's list at the given zero-relative\r
+        * index.\r
+        * \r
+        * @param values new item\r
+        * @param index the index for the item\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void add(final T value, final int index) {\r
+               checkWidget();\r
+               checkNullElement();\r
+               if (value == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               checkRange(index);\r
+\r
+               this.elements.add(index, value);\r
+               refresh();\r
+       }\r
+\r
+       /**\r
+        * Adds the argument to the end of the receiver's list.\r
+        * \r
+        * @param values new items\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void addAll(final List<T> values) {\r
+               checkWidget();\r
+               if (values == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (this.elements == null) {\r
+                       this.elements = new ArrayList<T>();\r
+               }\r
+               this.elements.addAll(values);\r
+               refresh();\r
+       }\r
+\r
+       /**\r
+        * Adds the argument to the end of the receiver's list.\r
+        * \r
+        * @param values new items\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the string is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void addAll(final T[] values) {\r
+               checkWidget();\r
+               if (values == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               if (this.elements == null) {\r
+                       this.elements = new ArrayList<T>();\r
+               }\r
+               for (final T value : values) {\r
+                       this.elements.add(value);\r
+               }\r
+               refresh();\r
+       }\r
+\r
+       /**\r
+        * Returns the item at the given, zero-relative index in the receiver's\r
+        * list. Throws an exception if the index is out of range.\r
+        * \r
+        * @param index the index of the item to return\r
+        * @return the item at the given index\r
+        * \r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public T getItem(final int index) {\r
+               checkWidget();\r
+               checkNullElement();\r
+               checkRange(index);\r
+\r
+               return this.elements.get(index);\r
+       }\r
+\r
+       /**\r
+        * Returns the number of items contained in the receiver's list.\r
+        * \r
+        * @return the number of items\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getItemCount() {\r
+               checkWidget();\r
+               if (this.elements == null) {\r
+                       return 0;\r
+               }\r
+\r
+               return this.elements.size();\r
+\r
+       }\r
+\r
+       /**\r
+        * Returns the list of items in the receiver's list.\r
+        * <p>\r
+        * Note: This is not the actual structure used by the receiver to maintain\r
+        * its list of items, so modifying the array will not affect the receiver.\r
+        * </p>\r
+        * \r
+        * @return the items in the receiver's list\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public List<T> getItems() {\r
+               checkWidget();\r
+               if (this.elements == null) {\r
+                       return null;\r
+               }\r
+               return new ArrayList<T>(this.elements);\r
+       }\r
+\r
+       /**\r
+        * Removes the item from the receiver's list at the given zero-relative\r
+        * index.\r
+        * \r
+        * @param index the index for the item\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void removeAt(final int index) {\r
+               checkWidget();\r
+               checkNullElement();\r
+               checkRange(index);\r
+               final Object removedElement = this.elements.remove(index);\r
+               this.selection.remove(removedElement);\r
+               refresh();\r
+       }\r
+\r
+       /**\r
+        * Searches the receiver's list starting at the first item until an item is\r
+        * found that is equal to the argument, and removes that item from the list.\r
+        * \r
+        * @param object the item to remove\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the object is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void remove(final T object) {\r
+               if (object == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               checkWidget();\r
+               checkNullElement();\r
+               this.elements.remove(object);\r
+               this.selection.remove(object);\r
+               refresh();\r
+       }\r
+\r
+       /**\r
+        * Remove all items of the receiver\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void removeAll() {\r
+               checkWidget();\r
+               checkNullElement();\r
+               if (this.elements != null) {\r
+                       this.elements.clear();\r
+               }\r
+               this.selection.clear();\r
+               refresh();\r
+       }\r
+\r
+       /**\r
+        * Sets the selection of the receiver. If the item was already selected, it\r
+        * remains selected.\r
+        * \r
+        * @param selection the new selection\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the selection is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+\r
+       public void setSelection(final Set<T> selection) {\r
+               checkWidget();\r
+               checkNullElement();\r
+               if (selection == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               this.selection = selection;\r
+               updateSelection();\r
+       }\r
+\r
+       /**\r
+        * Selects all selected items in the receiver's list.\r
+        * \r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void selectAll() {\r
+               checkWidget();\r
+               checkNullElement();\r
+               this.selection.addAll(this.elements);\r
+               updateSelection();\r
+       }\r
+\r
+       /**\r
+        * Selects the item at the given zero-relative index in the receiver's list.\r
+        * If the item at the index was already selected, it remains selected.\r
+        * \r
+        * @param index the index of the item to select\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void selectAt(final int index) {\r
+               checkWidget();\r
+               checkNullElement();\r
+               checkRange(index);\r
+               this.selection.add(this.elements.get(index));\r
+               updateSelection();\r
+       }\r
+\r
+       /**\r
+        * Selects an item the receiver's list. If the item was already selected, it\r
+        * remains selected.\r
+        * \r
+        * @param index the index of the item to select\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the selection is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void select(final T value) {\r
+               checkWidget();\r
+               checkNullElement();\r
+               if (!this.elements.contains(value)) {\r
+                       throw new IllegalArgumentException("Value not present in the widget");\r
+               }\r
+               this.selection.add(value);\r
+               updateSelection();\r
+       }\r
+\r
+       /**\r
+        * Selects items in the receiver. If the items were already selected, they\r
+        * remain selected.\r
+        * \r
+        * @param index the indexes of the items to select\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the selection is null</li>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setSelectedIndex(final int[] index) {\r
+               checkWidget();\r
+               checkNullElement();\r
+               for (final int i : index) {\r
+                       checkRange(i);\r
+                       this.selection.add(this.elements.get(i));\r
+               }\r
+               updateSelection();\r
+       }\r
+\r
+       /**\r
+        * Returns the zero-relative indices of the items which are currently\r
+        * selected in the receiver. The order of the indices is unspecified. The\r
+        * array is empty if no items are selected.\r
+        * <p>\r
+        * Note: This is not the actual structure used by the receiver to maintain\r
+        * its selection, so modifying the array will not affect the receiver.\r
+        * </p>\r
+        * \r
+        * @return the array of indices of the selected items\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int[] getSelectedIndex() {\r
+               checkWidget();\r
+               checkNullElement();\r
+               final List<Integer> selectedIndex = new ArrayList<Integer>();\r
+               for (int i = 0; i < this.elements.size(); i++) {\r
+                       if (this.selection.contains(this.elements.get(i))) {\r
+                               selectedIndex.add(i);\r
+                       }\r
+               }\r
+\r
+               final int[] returned = new int[selectedIndex.size()];\r
+               for (int i = 0; i < selectedIndex.size(); i++) {\r
+                       returned[i] = selectedIndex.get(i);\r
+               }\r
+\r
+               return returned;\r
+       }\r
+\r
+       /**\r
+        * Returns an array of <code>Object</code>s that are currently selected in\r
+        * the receiver. The order of the items is unspecified. An empty array\r
+        * indicates that no items are selected.\r
+        * <p>\r
+        * Note: This is not the actual structure used by the receiver to maintain\r
+        * its selection, so modifying the array will not affect the receiver.\r
+        * </p>\r
+        * \r
+        * @return an array representing the selection\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public List<T> getSelection() {\r
+               checkWidget();\r
+               checkNullElement();\r
+               return new ArrayList<T>(this.selection);\r
+       }\r
+\r
+       /**\r
+        * Deselects the item at the given zero-relative index in the receiver's\r
+        * list. If the item at the index was already deselected, it remains\r
+        * deselected. Indices that are out of range are ignored.\r
+        * \r
+        * @param index the index of the item to deselect\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void deselectAt(final int index) {\r
+               checkWidget();\r
+               checkNullElement();\r
+\r
+               if (index < 0 || index >= this.elements.size()) {\r
+                       SWT.error(SWT.ERROR_INVALID_RANGE);\r
+               }\r
+\r
+               this.selection.remove(index);\r
+               updateSelection();\r
+       }\r
+\r
+       /**\r
+        * Deselects the item in the receiver's list. If the item at the index was\r
+        * already deselected, it remains deselected.\r
+        * \r
+        * @param value the item to deselect\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_RANGE - if the index is not between 0\r
+        *                and the number of elements in the list minus 1 (inclusive)\r
+        *                </li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void deselect(final T value) {\r
+               checkWidget();\r
+               checkNullElement();\r
+               this.selection.remove(value);\r
+               updateSelection();\r
+       }\r
+\r
+       /**\r
+        * Deselects all items in the receiver's list.\r
+        * \r
+        * @param value the item to deselect\r
+        * @exception NullPointerException if there is no item in the receiver\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void deselectAll() {\r
+               checkWidget();\r
+               checkNullElement();\r
+               this.selection.clear();\r
+               updateSelection();\r
+       }\r
+\r
+       /**\r
+        * @return the number of columns\r
+        */\r
+       public int getNumberOfColumns() {\r
+               checkWidget();\r
+               return this.numberOfColumns;\r
+       }\r
+\r
+       /**\r
+        * @param numberOfColumns the number of columns\r
+        */\r
+       public void setNumberOfColumns(final int numberOfColumns) {\r
+               checkWidget();\r
+               this.numberOfColumns = numberOfColumns;\r
+               this.popup.dispose();\r
+               this.popup = null;\r
+               createPopup();\r
+       }\r
+\r
+       /**\r
+        * @return the separator used in the text field. Default value is ","\r
+        */\r
+       public String getSeparator() {\r
+               return this.separator;\r
+       }\r
+\r
+       /**\r
+        * @param separator the new value of the separator\r
+        */\r
+       public void setSeparator(final String separator) {\r
+               this.separator = separator;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#getForeground()\r
+        */\r
+       @Override\r
+       public Color getForeground() {\r
+               return this.foreground;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#setForeground(org.eclipse.swt.graphics.Color)\r
+        */\r
+       @Override\r
+       public void setForeground(final Color foreground) {\r
+               this.foreground = foreground;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#getBackground()\r
+        */\r
+       @Override\r
+       public Color getBackground() {\r
+               return this.background;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#setBackground(org.eclipse.swt.graphics.Color)\r
+        */\r
+       @Override\r
+       public void setBackground(final Color background) {\r
+               this.background = background;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#getFont()\r
+        */\r
+       @Override\r
+       public Font getFont() {\r
+               return this.font;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font)\r
+        */\r
+       @Override\r
+       public void setFont(final Font font) {\r
+               this.font = font;\r
+       }\r
+\r
+       /**\r
+        * Refresh the widget (after the add of a new element for example)\r
+        */\r
+       public void refresh() {\r
+               checkWidget();\r
+               this.popup.dispose();\r
+               this.popup = null;\r
+               createPopup();\r
+               updateSelection();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)\r
+        */\r
+       @Override\r
+       public Point computeSize(final int wHint, final int hHint, final boolean changed) {\r
+               checkWidget();\r
+               int width = 0, height = 0;\r
+\r
+               final GC gc = new GC(this.text);\r
+               final int spacer = gc.stringExtent(" ").x;\r
+               final int textWidth = gc.stringExtent(this.text.getText()).x;\r
+               gc.dispose();\r
+               final Point textSize = this.text.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);\r
+               final Point arrowSize = this.arrow.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);\r
+               final int borderWidth = getBorderWidth();\r
+\r
+               height = Math.max(textSize.y, arrowSize.y);\r
+               width = textWidth + 2 * spacer + arrowSize.x + 2 * borderWidth;\r
+               if (wHint != SWT.DEFAULT) {\r
+                       width = wHint;\r
+               }\r
+               if (hHint != SWT.DEFAULT) {\r
+                       height = hHint;\r
+               }\r
+               return new Point(width + 2 * borderWidth, height + 2 * borderWidth);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#setEnabled(boolean)\r
+        */\r
+       @Override\r
+       public void setEnabled(final boolean enabled) {\r
+               checkWidget();\r
+               this.arrow.setEnabled(enabled);\r
+               this.text.setEnabled(enabled);\r
+               super.setEnabled(enabled);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String)\r
+        */\r
+       @Override\r
+       public void setToolTipText(final String txt) {\r
+               checkWidget();\r
+               this.text.setToolTipText(txt);\r
+       }\r
+\r
+       /**\r
+        * @return the selection listener\r
+        */\r
+       public SelectionListener getSelectionListener() {\r
+               checkWidget();\r
+               return this.selectionListener;\r
+       }\r
+\r
+       /**\r
+        * @param selectionListener the new selection listener\r
+        */\r
+       public void setSelectionListener(final MultiChoiceSelectionListener<T> selectionListener) {\r
+               checkWidget();\r
+               this.selectionListener = selectionListener;\r
+               refresh();\r
+       }\r
+\r
+       /**\r
+        * Update the selection\r
+        */\r
+       public void updateSelection() {\r
+               checkWidget();\r
+               if (isDisposed()) {\r
+                       return;\r
+               }\r
+\r
+               if (this.popup == null || this.popup.isDisposed()) {\r
+                       return;\r
+               }\r
+\r
+               for (int i = 0; i < this.checkboxes.size(); i++) {\r
+                       final Button currentButton = this.checkboxes.get(i);\r
+                       if (!currentButton.isDisposed()) {\r
+                               final Object content = currentButton.getData();\r
+                               currentButton.setSelection(this.selection.contains(content));\r
+                       }\r
+               }\r
+               setLabel();\r
+\r
+       }\r
+\r
+       /**\r
+        * @return the last modified item\r
+        */\r
+       T getLastModified() {\r
+               return this.lastModified;\r
+       }\r
+\r
+       /**\r
+        * @return the popup\r
+        */\r
+       Shell getPopup() {\r
+               return this.popup;\r
+       }\r
+\r
+       /**\r
+        * Create the popup that contains all checkboxes\r
+        */\r
+       private void createPopup() {\r
+               this.popup = new Shell(getShell(), SWT.NO_TRIM | SWT.ON_TOP);\r
+               this.popup.setLayout(new GridLayout(this.numberOfColumns, true));\r
+\r
+               final int[] popupEvents = { SWT.Close, SWT.Paint, SWT.Deactivate, SWT.Dispose };\r
+               for (int i = 0; i < popupEvents.length; i++) {\r
+                       this.popup.addListener(popupEvents[i], this.listener);\r
+               }\r
+\r
+               if (this.elements == null) {\r
+                       return;\r
+               }\r
+\r
+               this.checkboxes = new ArrayList<Button>(this.elements.size());\r
+               for (final T o : this.elements) {\r
+                       final Button checkBoxButton = new Button(this.popup, SWT.CHECK);\r
+\r
+                       if (this.font != null) {\r
+                               checkBoxButton.setFont(this.font);\r
+                       }\r
+                       if (this.foreground != null) {\r
+                               checkBoxButton.setForeground(this.foreground);\r
+                       }\r
+                       if (this.background != null) {\r
+                               checkBoxButton.setBackground(this.background);\r
+                       }\r
+\r
+                       checkBoxButton.setData(o);\r
+                       checkBoxButton.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false));\r
+                       checkBoxButton.setText(o.toString());\r
+                       checkBoxButton.addSelectionListener(new SimpleSelectionAdapter() {\r
+                               @Override\r
+                               public void handle(final SelectionEvent e) {\r
+                                       if (checkBoxButton.getSelection()) {\r
+                                               MultiChoice.this.selection.add(o);\r
+                                       } else {\r
+                                               MultiChoice.this.selection.remove(o);\r
+                                       }\r
+                                       MultiChoice.this.lastModified = o;\r
+                                       setLabel();\r
+                               }\r
+                       });\r
+\r
+                       if (this.selectionListener != null) {\r
+                               checkBoxButton.addSelectionListener(this.selectionListener);\r
+                       }\r
+\r
+                       checkBoxButton.setSelection(this.selection.contains(o));\r
+                       this.checkboxes.add(checkBoxButton);\r
+               }\r
+               this.popup.layout();\r
+       }\r
+\r
+       /**\r
+        * Set the value of the label, based on the selected items\r
+        */\r
+       private void setLabel() {\r
+               if (this.checkboxes == null) {\r
+                       this.text.setText("");\r
+                       return;\r
+               }\r
+\r
+               final List<String> values = new ArrayList<String>();\r
+               for (final Button current : this.checkboxes) {\r
+                       if (current.getSelection()) {\r
+                               values.add(current.getText());\r
+                       }\r
+               }\r
+\r
+               final StringBuffer sb = new StringBuffer();\r
+               final Iterator<String> it = values.iterator();\r
+               while (it.hasNext()) {\r
+                       sb.append(it.next());\r
+                       if (it.hasNext()) {\r
+                               sb.append(this.separator);\r
+                       }\r
+               }\r
+\r
+               this.text.setText(sb.toString());\r
+       }\r
+\r
+       /**\r
+        * Handle a focus event\r
+        * \r
+        * @param type type of the event to handle\r
+        */\r
+       private void handleFocus(final int type) {\r
+               if (isDisposed()) {\r
+                       return;\r
+               }\r
+               switch (type) {\r
+               case SWT.FocusIn: {\r
+                       if (this.hasFocus) {\r
+                               return;\r
+                       }\r
+                       this.hasFocus = true;\r
+                       final Shell shell = getShell();\r
+                       shell.removeListener(SWT.Deactivate, this.listener);\r
+                       shell.addListener(SWT.Deactivate, this.listener);\r
+                       final Display display = getDisplay();\r
+                       display.removeFilter(SWT.FocusIn, this.filter);\r
+                       display.addFilter(SWT.FocusIn, this.filter);\r
+                       final Event e = new Event();\r
+                       notifyListeners(SWT.FocusIn, e);\r
+                       break;\r
+               }\r
+               case SWT.FocusOut: {\r
+                       if (!this.hasFocus) {\r
+                               return;\r
+                       }\r
+                       final Control focusControl = getDisplay().getFocusControl();\r
+                       if (focusControl == this.arrow) {\r
+                               return;\r
+                       }\r
+                       this.hasFocus = false;\r
+                       final Shell shell = getShell();\r
+                       shell.removeListener(SWT.Deactivate, this.listener);\r
+                       final Display display = getDisplay();\r
+                       display.removeFilter(SWT.FocusIn, this.filter);\r
+                       final Event e = new Event();\r
+                       notifyListeners(SWT.FocusOut, e);\r
+                       break;\r
+               }\r
+               default:\r
+                   break;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Handle a multichoice event\r
+        * \r
+        * @param event event to handle\r
+        */\r
+       private void multiChoiceEvent(final Event event) {\r
+               switch (event.type) {\r
+               case SWT.Dispose:\r
+                       if (this.popup != null && !this.popup.isDisposed()) {\r
+                               this.popup.dispose();\r
+                       }\r
+                       final Shell shell = getShell();\r
+                       shell.removeListener(SWT.Deactivate, this.listener);\r
+                       final Display display = getDisplay();\r
+                       display.removeFilter(SWT.FocusIn, this.filter);\r
+                       this.popup = null;\r
+                       this.arrow = null;\r
+                       break;\r
+               case SWT.Move:\r
+                       dropDown(false);\r
+                       break;\r
+               case SWT.Resize:\r
+                       if (isDropped()) {\r
+                               dropDown(false);\r
+                       }\r
+                       break;\r
+               default:\r
+                   break;\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Handle a button event\r
+        * \r
+        * @param event event to hangle\r
+        */\r
+       private void buttonEvent(final Event event) {\r
+               switch (event.type) {\r
+               case SWT.FocusIn: {\r
+                       handleFocus(SWT.FocusIn);\r
+                       break;\r
+               }\r
+               case SWT.Selection: {\r
+                       dropDown(!isDropped());\r
+                       break;\r
+               }\r
+               default:\r
+                   break;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return <code>true</code> if the popup is visible and not dropped,\r
+        *         <code>false</code> otherwise\r
+        */\r
+       private boolean isDropped() {\r
+               return !this.popup.isDisposed() && this.popup.getVisible();\r
+       }\r
+\r
+       /**\r
+        * Handle a popup event\r
+        * \r
+        * @param event event to handle\r
+        */\r
+       private void popupEvent(final Event event) {\r
+               switch (event.type) {\r
+               case SWT.Paint:\r
+                       final Rectangle listRect = this.popup.getBounds();\r
+                       final Color black = getDisplay().getSystemColor(SWT.COLOR_BLACK);\r
+                       event.gc.setForeground(black);\r
+                       event.gc.drawRectangle(0, 0, listRect.width - 1, listRect.height - 1);\r
+                       break;\r
+               case SWT.Close:\r
+                       event.doit = false;\r
+                       dropDown(false);\r
+                       break;\r
+               case SWT.Deactivate:\r
+                       dropDown(false);\r
+                       break;\r
+               case SWT.Dispose:\r
+                       if (this.checkboxes != null) {\r
+                               this.checkboxes.clear();\r
+                       }\r
+                       this.checkboxes = null;\r
+                       break;\r
+        default:\r
+            break;\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Display/Hide the popup window\r
+        * \r
+        * @param drop if <code>true</code>, displays the popup window. If\r
+        *            <code>false</code>, hide the popup window\r
+        */\r
+       private void dropDown(final boolean drop) {\r
+               if (drop == isDropped()) {\r
+                       return;\r
+               }\r
+\r
+               if (!drop) {\r
+                       this.popup.setVisible(false);\r
+                       if (!isDisposed()) {\r
+                               this.text.setFocus();\r
+                       }\r
+                       return;\r
+               }\r
+\r
+               if (getShell() != this.popup.getParent()) {\r
+                       this.popup.dispose();\r
+                       this.popup = null;\r
+                       createPopup();\r
+               }\r
+\r
+               final Point arrowRect = this.arrow.toDisplay(this.arrow.getSize().x - 5, this.arrow.getSize().y + this.arrow.getBorderWidth() - 3);\r
+               int x = arrowRect.x;\r
+               int y = arrowRect.y;\r
+\r
+               final Rectangle displayRect = getMonitor().getClientArea();\r
+               final Rectangle parentRect = getDisplay().map(getParent(), null, getBounds());\r
+               this.popup.pack();\r
+               final int width = this.popup.getBounds().width;\r
+               final int height = this.popup.getBounds().height;\r
+\r
+               if (y + height > displayRect.y + displayRect.height) {\r
+                       y = parentRect.y - height;\r
+               }\r
+               if (x + width > displayRect.x + displayRect.width) {\r
+                       x = displayRect.x + displayRect.width - width;\r
+               }\r
+\r
+               this.popup.setLocation(x, y);\r
+               this.popup.setVisible(true);\r
+               this.popup.setFocus();\r
+       }\r
+\r
+       /**\r
+        * Check if the elements attributes is not null\r
+        * \r
+        * @exception NullPointerException if there is no item in the receiver\r
+        */\r
+       private void checkNullElement() {\r
+               if (this.elements == null) {\r
+                       throw new NullPointerException("There is no element associated to this widget");\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @param index\r
+        * @throws NullPointerException\r
+        * @throws IllegalArgumentException\r
+        */\r
+       private void checkRange(final int index) throws NullPointerException {\r
+               checkNullElement();\r
+               if (index < 0 || index >= this.elements.size()) {\r
+                       SWT.error(SWT.ERROR_INVALID_RANGE);\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoiceSelectionListener.java b/org.tizen.common.externals/src/org/mihalis/opal/multiChoice/MultiChoiceSelectionListener.java
new file mode 100644 (file)
index 0000000..ac5ca79
--- /dev/null
@@ -0,0 +1,56 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.mihalis.opal.multiChoice;\r
+\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Shell;\r
+\r
+/**\r
+ * Classes which extend this abstract class provide methods that deal with the\r
+ * events that are generated when selection occurs in a MultiChoice control.\r
+ */\r
+public abstract class MultiChoiceSelectionListener<T> implements SelectionListener {\r
+       private final MultiChoice<T> parent;\r
+\r
+       public MultiChoiceSelectionListener(final MultiChoice<T> parent) {\r
+               this.parent = parent;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+        */\r
+       @Override\r
+       public final void widgetSelected(final SelectionEvent e) {\r
+               final Button button = (Button) e.widget;\r
+               handle(this.parent, this.parent.getLastModified(), button.getSelection(), this.parent.getPopup());\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)\r
+        */\r
+       @Override\r
+       public final void widgetDefaultSelected(final SelectionEvent inutile) {\r
+       }\r
+\r
+       /**\r
+        * This method contains the code that is called when the selection has\r
+        * changed\r
+        * \r
+        * @param parent MultiChoice responsible of the event\r
+        * @param receiver Object modified\r
+        * @param selected If <code>true</code>, the check box has been checked\r
+        * @param popup the popup window that contains all checkboxes\r
+        */\r
+       public abstract void handle(MultiChoice<T> parent, T receiver, boolean selected, Shell popup);\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/notify/Notifier.java b/org.tizen.common.externals/src/org/mihalis/opal/notify/Notifier.java
new file mode 100644 (file)
index 0000000..014a19c
--- /dev/null
@@ -0,0 +1,347 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation \r
+ *******************************************************************************/\r
+package org.mihalis.opal.notify;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.mihalis.opal.notify.NotifierColorsFactory.NotifierTheme;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * This class provides a notifier window, which is a window that appears in the\r
+ * bottom of the screen and slides.\r
+ */\r
+public class Notifier {\r
+       private static final int FONT_SIZE = 10;\r
+       private static final int MAX_DURATION_FOR_OPENING = 500;\r
+       private static final int DISPLAY_TIME = 4500;\r
+\r
+       private static final int FADE_TIMER = 50;\r
+       private static final int FADE_OUT_STEP = 8;\r
+\r
+       private static final int STEP = 5;\r
+\r
+       /**\r
+        * Starts a notification. A window will appear in the bottom of the screen,\r
+        * then will disappear after 4.5 s\r
+        * \r
+        * @param title the title of the popup window\r
+        * @param text the text of the notification\r
+        * \r
+        */\r
+       public static void notify(final String title, final String text) {\r
+               notify(null, title, text, NotifierTheme.YELLOW_THEME);\r
+       }\r
+\r
+       /**\r
+        * Starts a notification. A window will appear in the bottom of the screen,\r
+        * then will disappear after 4.5 s\r
+        * \r
+        * @param image the image to display (if <code>null</code>, a default image\r
+        *            is displayed)\r
+        * @param title the title of the popup window\r
+        * @param text the text of the notification\r
+        * \r
+        */\r
+       public static void notify(final Image image, final String title, final String text) {\r
+               notify(image, title, text, NotifierTheme.YELLOW_THEME);\r
+\r
+       }\r
+\r
+       /**\r
+        * Starts a notification. A window will appear in the bottom of the screen,\r
+        * then will disappear after 4.5 s\r
+        * \r
+        * @param title the title of the popup window\r
+        * @param text the text of the notification\r
+        * @param theme the graphical theme. If <code>null</code>, the yellow theme\r
+        *            is used\r
+        * \r
+        * @see NotifierTheme\r
+        */\r
+       public static void notify(final String title, final String text, final NotifierTheme theme) {\r
+               notify(null, title, text, theme);\r
+       }\r
+\r
+       /**\r
+        * Starts a notification. A window will appear in the bottom of the screen,\r
+        * then will disappear after 4.5 s\r
+        * \r
+        * @param image the image to display (if <code>null</code>, a default image\r
+        *            is displayed)\r
+        * @param title the title of the popup window\r
+        * @param text the text of the notification\r
+        * @param theme the graphical theme. If <code>null</code>, the yellow theme\r
+        *            is used\r
+        * \r
+        * @see NotifierTheme\r
+        */\r
+       public static void notify(final Image image, final String title, final String text, final NotifierTheme theme) {\r
+               final Shell shell = createNotificationWindow(image, title, text, NotifierColorsFactory.getColorsForTheme(theme));\r
+               makeShellAppears(shell);\r
+\r
+       }\r
+\r
+       /**\r
+        * Creates a notification window\r
+        * \r
+        * @param image image. If <code>null</code>, a default image is used\r
+        * @param title title, the title of the window\r
+        * @param text text of the window\r
+        * @param colors color set\r
+        * @return the notification window as a shell object\r
+        */\r
+       private static Shell createNotificationWindow(final Image image, final String title, final String text, final NotifierColors colors) {\r
+               final Shell shell = new Shell(SWT.NO_TRIM | SWT.NO_FOCUS);\r
+               shell.setLayout(new GridLayout(2, false));\r
+               shell.setBackgroundMode(SWT.INHERIT_FORCE);\r
+\r
+               createTitle(shell, title, colors);\r
+               createImage(shell, image);\r
+               createText(shell, text, colors);\r
+               createBackground(shell, colors);\r
+               createCloseAction(shell);\r
+\r
+               shell.addListener(SWT.Dispose, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               colors.dispose();\r
+                       }\r
+               });\r
+\r
+               shell.pack();\r
+               shell.setMinimumSize(320, 100);\r
+               return shell;\r
+       }\r
+\r
+       /**\r
+        * Creates the title part of the window\r
+        * \r
+        * @param shell the window\r
+        * @param title the title\r
+        * @param colors the color set\r
+        */\r
+       private static void createTitle(final Shell shell, final String title, final NotifierColors colors) {\r
+               final Label titleLabel = new Label(shell, SWT.NONE);\r
+               final GridData gdLabel = new GridData(GridData.BEGINNING, GridData.BEGINNING, true, false, 2, 1);\r
+               gdLabel.horizontalIndent = 40;\r
+               titleLabel.setLayoutData(gdLabel);\r
+               final Color titleColor = colors.titleColor;\r
+               titleLabel.setForeground(titleColor);\r
+\r
+               final Font titleFont = SWTGraphicUtil.buildFontFrom(titleLabel, SWT.BOLD, FONT_SIZE);\r
+               titleLabel.setFont(titleFont);\r
+               titleLabel.setText(title);\r
+               SWTGraphicUtil.dispose(shell, titleFont);\r
+       }\r
+\r
+       /**\r
+        * Creates the image part of the window\r
+        * \r
+        * @param shell the window\r
+        * @param image the image\r
+        */\r
+       private static void createImage(final Shell shell, final Image image) {\r
+               final Label labelImage = new Label(shell, SWT.NONE);\r
+               final GridData gdImage = new GridData(GridData.CENTER, GridData.BEGINNING, false, true);\r
+               gdImage.horizontalIndent = 10;\r
+               labelImage.setLayoutData(gdImage);\r
+               if (image == null) {\r
+                       final Image temp = SWTGraphicUtil.createImage("images/information.png");\r
+                       labelImage.setImage(temp);\r
+                       SWTGraphicUtil.dispose(shell, temp);\r
+               } else {\r
+                       labelImage.setImage(image);\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Creates the text part of the window\r
+        * \r
+        * @param shell the window\r
+        * @param text the text\r
+        * @param colors the color set\r
+        */\r
+       private static void createText(final Shell shell, final String text, final NotifierColors colors) {\r
+               final StyledText textLabel = new StyledText(shell, SWT.WRAP | SWT.READ_ONLY);\r
+               final GridData gdText = new GridData(GridData.FILL, GridData.FILL, true, true);\r
+               gdText.horizontalIndent = 15;\r
+               textLabel.setLayoutData(gdText);\r
+               textLabel.setEnabled(false);\r
+               final Font textFont = SWTGraphicUtil.buildFontFrom(textLabel, SWT.NONE, 10);\r
+               textLabel.setFont(textFont);\r
+\r
+               final Color textColor = colors.textColor;\r
+               textLabel.setForeground(textColor);\r
+\r
+               textLabel.setText("<html><body>" + text + "</body></html>");\r
+               SWTGraphicUtil.applyHTMLFormating(textLabel);\r
+\r
+               SWTGraphicUtil.dispose(shell, textFont);\r
+\r
+       }\r
+\r
+       /**\r
+        * Creates the background of the window\r
+        * \r
+        * @param shell the window\r
+        * @param colors the color set of the window\r
+        */\r
+       private static void createBackground(final Shell shell, final NotifierColors colors) {\r
+               shell.addListener(SWT.Resize, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final Rectangle rect = shell.getClientArea();\r
+                               final Image newImage = new Image(Display.getDefault(), Math.max(1, rect.width), rect.height);\r
+                               final GC gc = new GC(newImage);\r
+                               gc.setAntialias(SWT.ON);\r
+\r
+                               final Color borderColor = colors.borderColor;\r
+                               final Color fillColor1 = colors.leftColor;\r
+                               final Color fillColor2 = colors.rightColor;\r
+\r
+                               gc.setBackground(borderColor);\r
+                               gc.fillRoundRectangle(0, 0, rect.width, rect.height, 8, 8);\r
+\r
+                               gc.setBackground(fillColor1);\r
+                               gc.fillRoundRectangle(1, 1, rect.width - 2, rect.height - 2, 8, 8);\r
+\r
+                               gc.setBackground(fillColor2);\r
+                               gc.fillRoundRectangle(30, 1, rect.width - 32, rect.height - 2, 8, 8);\r
+                               gc.fillRectangle(30, 1, 10, rect.height - 2);\r
+\r
+                               final Image closeImage = SWTGraphicUtil.createImage("images/close.png");\r
+                               gc.drawImage(closeImage, rect.width - 21, 13);\r
+\r
+                               gc.dispose();\r
+                               closeImage.dispose();\r
+\r
+                               shell.setBackgroundImage(newImage);\r
+\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * @param shell shell that will appear\r
+        */\r
+       private static void makeShellAppears(final Shell shell) {\r
+               if (shell == null || shell.isDisposed()) {\r
+                       return;\r
+               }\r
+\r
+               final Rectangle clientArea = Display.getDefault().getActiveShell().getMonitor().getClientArea();\r
+               final int startX = clientArea.x + clientArea.width - shell.getSize().x;\r
+\r
+               final int stepForPosition = MAX_DURATION_FOR_OPENING / shell.getSize().y * STEP;\r
+               final int stepForAlpha = STEP * 255 / shell.getSize().y;\r
+\r
+               final int lastPosition = clientArea.y + clientArea.height - shell.getSize().y;\r
+\r
+               shell.setAlpha(0);\r
+               shell.setLocation(startX, clientArea.y + clientArea.height);\r
+               shell.open();\r
+\r
+               shell.getDisplay().timerExec(stepForPosition, new Runnable() {\r
+\r
+                       @Override\r
+                       public void run() {\r
+\r
+                               if (shell == null || shell.isDisposed()) {\r
+                                       return;\r
+                               }\r
+\r
+                               shell.setLocation(startX, shell.getLocation().y - STEP);\r
+                               shell.setAlpha(shell.getAlpha() + stepForAlpha);\r
+                               if (shell.getLocation().y >= lastPosition) {\r
+                                       shell.getDisplay().timerExec(stepForPosition, this);\r
+                               } else {\r
+                                       shell.setAlpha(255);\r
+                                       Display.getDefault().timerExec(DISPLAY_TIME, fadeOut(shell, false));\r
+                               }\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * @param shell shell that will disappear\r
+        * @param fast if true, the fading is much faster\r
+        * @return a runnable\r
+        */\r
+       private static Runnable fadeOut(final Shell shell, final boolean fast) {\r
+               return new Runnable() {\r
+\r
+                       @Override\r
+                       public void run() {\r
+                               if (shell == null || shell.isDisposed()) {\r
+                                       return;\r
+                               }\r
+\r
+                               int currentAlpha = shell.getAlpha();\r
+                               currentAlpha -= FADE_OUT_STEP * (fast ? 8 : 1);\r
+\r
+                               if (currentAlpha <= 0) {\r
+                                       shell.setAlpha(0);\r
+                                       shell.dispose();\r
+                                       return;\r
+                               }\r
+\r
+                               shell.setAlpha(currentAlpha);\r
+\r
+                               Display.getDefault().timerExec(FADE_TIMER, this);\r
+\r
+                       }\r
+\r
+               };\r
+       }\r
+\r
+       /**\r
+        * Add a listener to the shell in order to handle the clicks on the close\r
+        * button\r
+        * \r
+        * @param shell associated shell\r
+        */\r
+       private static void createCloseAction(final Shell shell) {\r
+               shell.addListener(SWT.MouseUp, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final Rectangle rect = shell.getClientArea();\r
+                               final int xUpperLeftCorner = rect.width - 21;\r
+                               final int yUpperLeftCorner = 13;\r
+\r
+                               if (event.x >= xUpperLeftCorner && event.x <= xUpperLeftCorner + 8 && event.y >= yUpperLeftCorner && event.y <= yUpperLeftCorner + 8) {\r
+                                       Display.getDefault().timerExec(0, fadeOut(shell, true));\r
+                               }\r
+\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/notify/NotifierColors.java b/org.tizen.common.externals/src/org/mihalis/opal/notify/NotifierColors.java
new file mode 100644 (file)
index 0000000..ddde663
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation \r
+ *******************************************************************************/\r
+package org.mihalis.opal.notify;\r
+\r
+import org.eclipse.swt.graphics.Color;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * This class is a simple POJO that holds colors used by the Notifier widget\r
+ * \r
+ */\r
+class NotifierColors {\r
+       Color titleColor;\r
+       Color textColor;\r
+       Color borderColor;\r
+       Color leftColor;\r
+       Color rightColor;\r
+\r
+       void dispose() {\r
+               SWTGraphicUtil.dispose(this.titleColor);\r
+               SWTGraphicUtil.dispose(this.borderColor);\r
+               SWTGraphicUtil.dispose(this.leftColor);\r
+               SWTGraphicUtil.dispose(this.rightColor);\r
+               SWTGraphicUtil.dispose(this.textColor);\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/notify/NotifierColorsFactory.java b/org.tizen.common.externals/src/org/mihalis/opal/notify/NotifierColorsFactory.java
new file mode 100644 (file)
index 0000000..1839063
--- /dev/null
@@ -0,0 +1,66 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON All rights reserved. This program and the\r
+ * accompanying materials are made available under the terms of the Eclipse\r
+ * Public License v1.0 which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors: Laurent CARON (laurent.caron at gmail dot com) - initial API\r
+ * and implementation\r
+ *******************************************************************************/\r
+\r
+package org.mihalis.opal.notify;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.widgets.Display;\r
+\r
+/**\r
+ * This class creates the colors associated to a given theme\r
+ * \r
+ */\r
+public class NotifierColorsFactory {\r
+\r
+       public enum NotifierTheme {\r
+               YELLOW_THEME, GRAY_THEME, BLUE_THEME\r
+       };\r
+\r
+       /**\r
+        * Constructor\r
+        */\r
+       private NotifierColorsFactory() {\r
+\r
+       }\r
+\r
+       /**\r
+        * @param theme a theme for the notifier widget\r
+        * @return the color set for the given theme\r
+        */\r
+       static NotifierColors getColorsForTheme(final NotifierTheme theme) {\r
+               final NotifierColors colors = new NotifierColors();\r
+               switch (theme) {\r
+               case BLUE_THEME:\r
+                       colors.textColor = new Color(Display.getDefault(), 4, 64, 140);\r
+                       colors.titleColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK);\r
+                       colors.borderColor = new Color(Display.getDefault(), 153, 188, 232);\r
+                       colors.leftColor = new Color(Display.getDefault(), 210, 225, 244);\r
+                       colors.rightColor = new Color(Display.getDefault(), 182, 207, 238);\r
+                       break;\r
+               case GRAY_THEME:\r
+                       colors.textColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK);\r
+                       colors.titleColor = Display.getDefault().getSystemColor(SWT.COLOR_DARK_RED);\r
+                       colors.borderColor = new Color(Display.getDefault(), 208, 208, 208);\r
+                       colors.leftColor = new Color(Display.getDefault(), 255, 255, 255);\r
+                       colors.rightColor = new Color(Display.getDefault(), 208, 208, 208);\r
+                       break;\r
+               default:\r
+                       colors.textColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK);\r
+                       colors.titleColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK);\r
+                       colors.borderColor = new Color(Display.getDefault(), 218, 178, 85);\r
+                       colors.leftColor = new Color(Display.getDefault(), 220, 220, 160);\r
+                       colors.rightColor = new Color(Display.getDefault(), 255, 255, 191);\r
+                       break;\r
+               }\r
+               return colors;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/ChoiceItem.java b/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/ChoiceItem.java
new file mode 100644 (file)
index 0000000..cff7959
--- /dev/null
@@ -0,0 +1,56 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *     Eugene Ryzhikov - Author of the Oxbow Project (http://code.google.com/p/oxbow/) - Inspiration\r
+ *******************************************************************************/\r
+package org.mihalis.opal.opalDialog;\r
+\r
+/**\r
+ * Instances of this class are choice items used by the choice widget\r
+ */\r
+public class ChoiceItem {\r
+\r
+       private final String instruction;\r
+       private final String text;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param instruction instruction of the choice\r
+        * @param text text displayed under the instruction\r
+        */\r
+       public ChoiceItem(final String instruction, final String text) {\r
+               this.instruction = instruction;\r
+               this.text = text;\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param instruction instruction\r
+        */\r
+       public ChoiceItem(final String instruction) {\r
+               this(instruction, null);\r
+       }\r
+\r
+       /**\r
+        * @return the instruction\r
+        */\r
+       public String getInstruction() {\r
+               return this.instruction;\r
+       }\r
+\r
+       /**\r
+        * @return the text\r
+        */\r
+       public String getText() {\r
+               return this.text;\r
+       };\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/ChoiceWidget.java b/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/ChoiceWidget.java
new file mode 100644 (file)
index 0000000..24bcf99
--- /dev/null
@@ -0,0 +1,301 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *     Eugene Ryzhikov - Author of the Oxbow Project (http://code.google.com/p/oxbow/) - Inspiration\r
+ *******************************************************************************/\r
+package org.mihalis.opal.opalDialog;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instance of this class are composite that represents a choice like in Windows\r
+ * Vista and Seven. It is composed of a green arrow, instruction and text\r
+ */\r
+public class ChoiceWidget extends Composite {\r
+       private Image oldImage;\r
+\r
+       private ChoiceItem choiceItem;\r
+\r
+       private Label image;\r
+       private Label instruction;\r
+       private Label text;\r
+\r
+       private final List<SelectionListener> selectionListeners;\r
+\r
+       private boolean selection;\r
+       private boolean insideComposite;\r
+       private boolean insideImage;\r
+       private boolean insideText;\r
+       private boolean insideInstruction;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a widget which will be the parent of the new instance\r
+        *            (cannot be null)\r
+        * @param style the style of widget to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        * @see Composite#Composite(Composite, int)\r
+        * @see SWT#NO_BACKGROUND\r
+        * @see SWT#NO_FOCUS\r
+        * @see SWT#NO_MERGE_PAINTS\r
+        * @see SWT#NO_REDRAW_RESIZE\r
+        * @see SWT#NO_RADIO_GROUP\r
+        * @see SWT#EMBEDDED\r
+        * @see SWT#DOUBLE_BUFFERED\r
+        * @see Widget#getStyle\r
+        */\r
+       public ChoiceWidget(final Composite parent, final int style) {\r
+               super(parent, style);\r
+\r
+               this.setBackgroundMode(SWT.INHERIT_DEFAULT);\r
+               this.setLayout(new GridLayout(2, false));\r
+\r
+               buildGreenArrow();\r
+               buildInstruction();\r
+               buildText();\r
+               addMouseListeners();\r
+\r
+               this.selectionListeners = new ArrayList<SelectionListener>();\r
+               this.addListener(SWT.Resize, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               drawComposite();\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Build the green arrow\r
+        */\r
+       private void buildGreenArrow() {\r
+               this.image = new Label(this, SWT.NONE);\r
+               this.image.setImage(SWTGraphicUtil.createImage("images/arrowGreenRight.png"));\r
+               this.image.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+               this.image.setLayoutData(new GridData(GridData.CENTER, GridData.BEGINNING, false, false, 1, 2));\r
+       }\r
+\r
+       /**\r
+        * Build the instruction\r
+        */\r
+       private void buildInstruction() {\r
+               final Color color = new Color(Display.getCurrent(), 35, 107, 178);\r
+               addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(color);\r
+                       }\r
+               });\r
+               this.instruction = new Label(this, SWT.NONE);\r
+               this.instruction.setForeground(color);\r
+               this.instruction.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false));\r
+       }\r
+\r
+       /**\r
+        * Build the panel\r
+        */\r
+       private void buildText() {\r
+               this.text = new Label(this, SWT.NONE);\r
+               this.text.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));\r
+               this.text.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, false, true));\r
+       }\r
+\r
+       /**\r
+        * Add mouse listeners\r
+        */\r
+       private void addMouseListeners() {\r
+               final Listener mouseEnterListener = new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+\r
+                               if (event.widget.equals(ChoiceWidget.this)) {\r
+                                       ChoiceWidget.this.insideComposite = true;\r
+                               }\r
+\r
+                               if (event.widget.equals(ChoiceWidget.this.image)) {\r
+                                       ChoiceWidget.this.insideImage = true;\r
+                               }\r
+                               if (event.widget.equals(ChoiceWidget.this.text)) {\r
+                                       ChoiceWidget.this.insideText = true;\r
+                               }\r
+                               if (event.widget.equals(ChoiceWidget.this.instruction)) {\r
+                                       ChoiceWidget.this.insideInstruction = true;\r
+                               }\r
+\r
+                               drawComposite();\r
+                       }\r
+               };\r
+\r
+               final Listener mouseExitListener = new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               if (event.widget.equals(ChoiceWidget.this)) {\r
+                                       ChoiceWidget.this.insideComposite = false;\r
+                               }\r
+\r
+                               if (event.widget.equals(ChoiceWidget.this.image)) {\r
+                                       ChoiceWidget.this.insideImage = false;\r
+                               }\r
+                               if (event.widget.equals(ChoiceWidget.this.text)) {\r
+                                       ChoiceWidget.this.insideText = false;\r
+                               }\r
+                               if (event.widget.equals(ChoiceWidget.this.instruction)) {\r
+                                       ChoiceWidget.this.insideInstruction = false;\r
+                               }\r
+                               drawComposite();\r
+                       }\r
+               };\r
+\r
+               final Listener mouseClickListener = new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               for (final SelectionListener selectionListener : ChoiceWidget.this.selectionListeners) {\r
+                                       selectionListener.widgetSelected(null);\r
+                               }\r
+                       }\r
+               };\r
+\r
+               addListener(SWT.MouseEnter, mouseEnterListener);\r
+               this.image.addListener(SWT.MouseEnter, mouseEnterListener);\r
+               this.text.addListener(SWT.MouseEnter, mouseEnterListener);\r
+               this.instruction.addListener(SWT.MouseEnter, mouseEnterListener);\r
+\r
+               addListener(SWT.MouseExit, mouseExitListener);\r
+               this.image.addListener(SWT.MouseExit, mouseExitListener);\r
+               this.text.addListener(SWT.MouseExit, mouseExitListener);\r
+               this.instruction.addListener(SWT.MouseExit, mouseExitListener);\r
+\r
+               addListener(SWT.MouseUp, mouseClickListener);\r
+               this.image.addListener(SWT.MouseUp, mouseClickListener);\r
+               this.text.addListener(SWT.MouseUp, mouseClickListener);\r
+               this.instruction.addListener(SWT.MouseUp, mouseClickListener);\r
+       }\r
+\r
+       /**\r
+        * Draw the composite\r
+        */\r
+       private void drawComposite() {\r
+\r
+               final Rectangle rect = this.getClientArea();\r
+               final Image newImage = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height));\r
+\r
+               final GC gc = new GC(newImage);\r
+\r
+               final boolean inside = this.insideComposite || this.insideImage || this.insideInstruction || this.insideText;\r
+\r
+               if (!inside && !this.selection) {\r
+                       gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+                       gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+                       gc.drawRectangle(rect.x, rect.y, rect.width, rect.height);\r
+               } else {\r
+                       // The mouse is over OR the item is selected\r
+                       final Color gradientColor = inside ? new Color(getDisplay(), 220, 231, 243) : new Color(getDisplay(), 241, 241, 241);\r
+                       final Color borderColor = inside ? new Color(getDisplay(), 35, 107, 178) : new Color(getDisplay(), 192, 192, 192);\r
+\r
+                       gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+                       gc.setBackground(gradientColor);\r
+                       gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true);\r
+\r
+                       gc.setForeground(borderColor);\r
+                       gc.drawRoundRectangle(rect.x, rect.y, rect.width - 1, rect.height - 1, 2, 2);\r
+\r
+                       gradientColor.dispose();\r
+                       borderColor.dispose();\r
+               }\r
+               gc.dispose();\r
+\r
+               this.setBackgroundImage(newImage);\r
+               if (this.oldImage != null) {\r
+                       this.oldImage.dispose();\r
+               }\r
+               this.oldImage = newImage;\r
+\r
+       }\r
+\r
+       /**\r
+        * @return the current choice item\r
+        */\r
+       public ChoiceItem getChoiceItem() {\r
+               return this.choiceItem;\r
+       }\r
+\r
+       /**\r
+        * @param choiceItem the choiceItem to set\r
+        */\r
+       public void setChoiceItem(final ChoiceItem choiceItem) {\r
+               this.choiceItem = choiceItem;\r
+               this.instruction.setText(choiceItem.getInstruction());\r
+               this.text.setText(choiceItem.getText());\r
+       }\r
+\r
+       /**\r
+        * Add a selection listener to this widget\r
+        * \r
+        * @param listener listener to add\r
+        */\r
+       public void addSelectionListener(final SelectionListener listener) {\r
+               this.selectionListeners.add(listener);\r
+       }\r
+\r
+       /**\r
+        * Remove a selection listener\r
+        * \r
+        * @param listener listener to remove\r
+        */\r
+       public void removeSelectionListener(final SelectionListener listener) {\r
+               this.selectionListeners.remove(listener);\r
+       }\r
+\r
+       public void setSelection(final boolean selection) {\r
+               this.selection = selection;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/Dialog.java b/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/Dialog.java
new file mode 100644 (file)
index 0000000..914ab12
--- /dev/null
@@ -0,0 +1,480 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *     Eugene Ryzhikov - Author of the Oxbow Project (http://code.google.com/p/oxbow/) - Inspiration\r
+ *******************************************************************************/\r
+package org.mihalis.opal.opalDialog;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+\r
+/**\r
+ * Instances of this class are dialog box\r
+ */\r
+public class Dialog {\r
+\r
+       /**\r
+        * Types of opal dialog\r
+        */\r
+       public enum OpalDialogType {\r
+               CLOSE, YES_NO, OK, OK_CANCEL, SELECT_CANCEL, NO_BUTTON, OTHER, NONE\r
+       }\r
+\r
+       private String title;\r
+       OpalDialogType buttonType;\r
+       private final MessageArea messageArea;\r
+       private final FooterArea footerArea;\r
+       final Shell shell;\r
+\r
+       private int minimumWidth = 300;\r
+       private int minimumHeight = 150;\r
+\r
+       /**\r
+        * Constructor\r
+        */\r
+       public Dialog() {\r
+               this(null);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param parent parent shell\r
+        */\r
+       public Dialog(final Shell parent) {\r
+               if (parent == null) {\r
+                       this.shell = new Shell(Display.getCurrent(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);\r
+               } else {\r
+                       this.shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);\r
+               }\r
+               this.messageArea = new MessageArea(this);\r
+               this.footerArea = new FooterArea(this);\r
+       }\r
+\r
+       /**\r
+        * Show the dialog box\r
+        * \r
+        * @return the index of the selected button\r
+        */\r
+       public int show() {\r
+               final GridLayout gd = new GridLayout(1, true);\r
+               gd.horizontalSpacing = 0;\r
+               gd.verticalSpacing = 0;\r
+               gd.marginHeight = gd.marginWidth = 0;\r
+               this.shell.setLayout(gd);\r
+\r
+               this.messageArea.render();\r
+               this.footerArea.render();\r
+               if (this.title != null) {\r
+                       this.shell.setText(this.title);\r
+               }\r
+               pack();\r
+               this.shell.open();\r
+\r
+               final Display display = this.shell.getDisplay();\r
+               while (!this.shell.isDisposed()) {\r
+                       if (!display.readAndDispatch()) {\r
+                               display.sleep();\r
+                       }\r
+               }\r
+\r
+               return this.footerArea.getSelectedButton();\r
+       }\r
+\r
+       /**\r
+        * Close the dialog box\r
+        */\r
+       public void close() {\r
+               this.shell.dispose();\r
+\r
+       }\r
+\r
+       /**\r
+        * Compute the size of the shell\r
+        */\r
+       void pack() {\r
+\r
+               final Point preferredSize = this.shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+\r
+               if (preferredSize.x < this.minimumWidth) {\r
+\r
+                       preferredSize.x = this.minimumWidth;\r
+               }\r
+               if (preferredSize.y < this.minimumHeight) {\r
+                       preferredSize.y = this.minimumHeight;\r
+               }\r
+\r
+               final Point displaySize = new Point(this.shell.getDisplay().getBounds().width, this.shell.getDisplay().getBounds().height);\r
+\r
+               final int centerX = (displaySize.x - preferredSize.x) / 2;\r
+               final int centerY = (displaySize.y - preferredSize.y) / 2;\r
+\r
+               this.shell.setBounds(centerX, centerY, preferredSize.x, preferredSize.y);\r
+       }\r
+\r
+       // ------------------------------------------- Convenient methods\r
+\r
+       /**\r
+        * Create a dialog box that asks a question\r
+        * \r
+        * @param title title of the dialog box\r
+        * @param text text of the question\r
+        * @param defaultValue default value of the input\r
+        * @return the value typed by the user\r
+        */\r
+       public static String ask(final String title, final String text, final String defaultValue) {\r
+               return ask(null, title, text, defaultValue);\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box that asks a question\r
+        * \r
+        * @shell parent shell\r
+        * @param title title of the dialog box\r
+        * @param text text of the question\r
+        * @param defaultValue default value of the input\r
+        * @return the value typed by the user\r
+        */\r
+       public static String ask(final Shell shell, final String title, final String text, final String defaultValue) {\r
+               final Dialog dialog = new Dialog(shell);\r
+               dialog.setTitle(ResourceManager.getLabel(ResourceManager.INPUT));\r
+               dialog.getMessageArea().setTitle(title).setText(text).setIcon(Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION)).addTextBox(defaultValue);\r
+               dialog.setButtonType(OpalDialogType.OK_CANCEL);\r
+               if (dialog.show() == 0) {\r
+                       return dialog.getMessageArea().getTextBoxValue();\r
+               } else {\r
+                       return null;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box that displays an error message\r
+        * \r
+        * @param title title of the dialog box\r
+        * @param errorMessage Error message\r
+        */\r
+       public static void error(final String title, final String errorMessage) {\r
+               error(null, title, errorMessage);\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box that displays an error message\r
+        * \r
+        * @param shell parent shell\r
+        * @param title title of the dialog box\r
+        * @param errorMessage Error message\r
+        */\r
+       public static void error(final Shell shell, final String title, final String errorMessage) {\r
+               final Dialog dialog = new Dialog(shell);\r
+               dialog.setTitle(ResourceManager.getLabel(ResourceManager.APPLICATION_ERROR));\r
+               dialog.getMessageArea().setTitle(title).//\r
+                               setText(errorMessage).//\r
+                               setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR));\r
+               dialog.setButtonType(OpalDialogType.OK);\r
+               dialog.show();\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box that inform the user\r
+        * \r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        */\r
+       public static void inform(final String title, final String text) {\r
+               inform(null, title, text);\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box that inform the user\r
+        * \r
+        * @param shell parent shell\r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        */\r
+       public static void inform(final Shell shell, final String title, final String text) {\r
+               final Dialog dialog = new Dialog(shell);\r
+               dialog.setTitle(ResourceManager.getLabel(ResourceManager.INFORMATION));\r
+               dialog.getMessageArea().setTitle(title).setText(text).setIcon(Display.getCurrent().getSystemImage(SWT.ICON_INFORMATION));\r
+               dialog.setButtonType(OpalDialogType.CLOSE);\r
+               dialog.show();\r
+\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box that asks the user a confirmation\r
+        * \r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        * @return <code>true</code> if the user confirmed, <code>false</code>\r
+        *         otherwise\r
+        */\r
+       public static boolean isConfirmed(final String title, final String text) {\r
+               return isConfirmed(null, title, text, -1);\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box that asks the user a confirmation\r
+        * \r
+        * @param shell parent shell\r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        * @return <code>true</code> if the user confirmed, <code>false</code>\r
+        *         otherwise\r
+        */\r
+       public static boolean isConfirmed(final Shell shell, final String title, final String text) {\r
+               return isConfirmed(shell, title, text, -1);\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box that asks the user a confirmation. The button "yes"\r
+        * is not enabled before timer seconds\r
+        * \r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        * @param timer number of seconds before enabling the yes button\r
+        * @return <code>true</code> if the user confirmed, <code>false</code>\r
+        *         otherwise\r
+        */\r
+       public static boolean isConfirmed(final String title, final String text, final int timer) {\r
+               return isConfirmed(null, title, text, timer);\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box that asks the user a confirmation. The button "yes"\r
+        * is not enabled before timer seconds\r
+        * \r
+        * @param shell parent shell\r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        * @param timer number of seconds before enabling the yes button\r
+        * @return <code>true</code> if the user confirmed, <code>false</code>\r
+        *         otherwise\r
+        */\r
+       public static boolean isConfirmed(final Shell shell, final String title, final String text, final int timer) {\r
+               final Dialog dialog = new Dialog(shell);\r
+               dialog.setTitle(ResourceManager.getLabel(ResourceManager.WARNING));\r
+               dialog.getMessageArea().setTitle(title).setText(text).setIcon(Display.getCurrent().getSystemImage(SWT.ICON_WARNING));\r
+\r
+               dialog.getFooterArea().setTimer(timer).setTimerIndexButton(0);\r
+               dialog.setButtonType(OpalDialogType.YES_NO);\r
+               return dialog.show() == 0;\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box with a radio choice\r
+        * \r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        * @param defaultSelection index of the default selection\r
+        * @param values values to display\r
+        * @return the index of the selection\r
+        */\r
+       public static int radioChoice(final String title, final String text, final int defaultSelection, final String... values) {\r
+               return radioChoice(null, title, text, defaultSelection, values);\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box with a radio choice\r
+        * \r
+        * @param shell parent shell\r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        * @param defaultSelection index of the default selection\r
+        * @param values values to display\r
+        * @return the index of the selection\r
+        */\r
+       public static int radioChoice(final Shell shell, final String title, final String text, final int defaultSelection, final String... values) {\r
+               final Dialog dialog = new Dialog(shell);\r
+               dialog.setTitle(ResourceManager.getLabel(ResourceManager.CHOICE));\r
+               dialog.getMessageArea().setTitle(title).setText(text).setIcon(Display.getCurrent().getSystemImage(SWT.ICON_QUESTION)).addRadioButtons(defaultSelection, values);\r
+               dialog.setButtonType(OpalDialogType.SELECT_CANCEL);\r
+               if (dialog.show() == 0) {\r
+                       return dialog.getMessageArea().getRadioChoice();\r
+               } else {\r
+                       return -1;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Display a dialog box with an exception\r
+        * \r
+        * @param exception exception to display\r
+        */\r
+       public static void showException(final Throwable exception) {\r
+               final Dialog dialog = new Dialog();\r
+               dialog.setTitle(ResourceManager.getLabel(ResourceManager.EXCEPTION));\r
+\r
+               final String msg = exception.getMessage();\r
+               final String className = exception.getClass().getName();\r
+               final boolean noMessage = msg == null || msg.trim().length() == 0;\r
+\r
+               dialog.getMessageArea().setTitle(noMessage ? className : msg).//\r
+                               setText(noMessage ? "" : className).//\r
+                               setIcon(Display.getCurrent().getSystemImage(SWT.ICON_ERROR)).//\r
+                               setException(exception);\r
+\r
+               dialog.getFooterArea().setExpanded(true);\r
+\r
+               dialog.setButtonType(OpalDialogType.CLOSE);\r
+               dialog.show();\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box with a choice\r
+        * \r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        * @param defaultSelection index of the default selection\r
+        * @param items items to display\r
+        * @return the index of the selected value\r
+        */\r
+       public static int choice(final String title, final String text, final int defaultSelection, final ChoiceItem... items) {\r
+               return choice(null, title, text, defaultSelection, items);\r
+       }\r
+\r
+       /**\r
+        * Create a dialog box with a choice\r
+        * \r
+        * @param shell parent shell\r
+        * @param title title of the dialog box\r
+        * @param text text to display\r
+        * @param defaultSelection index of the default selection\r
+        * @param items items to display\r
+        * @return the index of the selected value\r
+        */\r
+       public static int choice(final Shell shell, final String title, final String text, final int defaultSelection, final ChoiceItem... items) {\r
+               final Dialog dialog = new Dialog(shell);\r
+               dialog.setTitle(ResourceManager.getLabel(ResourceManager.CHOICE));\r
+               dialog.getMessageArea().setTitle(title).setText(text).setIcon(Display.getCurrent().getSystemImage(SWT.ICON_QUESTION)).addChoice(defaultSelection, items);\r
+               dialog.setButtonType(OpalDialogType.NONE);\r
+               dialog.show();\r
+               return dialog.getMessageArea().getChoice();\r
+       }\r
+\r
+       // ------------------------------------------- Getters & Setters\r
+\r
+       /**\r
+        * @return the title\r
+        */\r
+       public String getTitle() {\r
+               return this.title;\r
+       }\r
+\r
+       /**\r
+        * @param title the title to set\r
+        */\r
+       public void setTitle(final String title) {\r
+               this.title = title;\r
+       }\r
+\r
+       /**\r
+        * @return the buttonType\r
+        */\r
+       public OpalDialogType getButtonType() {\r
+               return this.buttonType;\r
+       }\r
+\r
+       /**\r
+        * @param buttonType the buttonType to set\r
+        */\r
+       public void setButtonType(final OpalDialogType buttonType) {\r
+               this.buttonType = buttonType;\r
+\r
+               switch (buttonType) {\r
+               case CLOSE:\r
+                       this.footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.CLOSE)).setDefaultButtonIndex(0);\r
+                       break;\r
+               case NO_BUTTON:\r
+                       break;\r
+               case OK:\r
+                       this.footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.OK)).setDefaultButtonIndex(0);\r
+                       break;\r
+               case OK_CANCEL:\r
+                       this.footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.OK), ResourceManager.getLabel(ResourceManager.CANCEL)).setDefaultButtonIndex(-1);\r
+                       break;\r
+               case SELECT_CANCEL:\r
+                       this.footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.SELECT), ResourceManager.getLabel(ResourceManager.CANCEL)).setDefaultButtonIndex(-1);\r
+                       break;\r
+               case YES_NO:\r
+                       this.footerArea.setButtonLabels(ResourceManager.getLabel(ResourceManager.YES), ResourceManager.getLabel(ResourceManager.NO)).setDefaultButtonIndex(0);\r
+                       break;\r
+               default:\r
+                       break;\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * @return the messageArea\r
+        */\r
+       public MessageArea getMessageArea() {\r
+               return this.messageArea;\r
+       }\r
+\r
+       /**\r
+        * @return the footerArea\r
+        */\r
+       public FooterArea getFooterArea() {\r
+               return this.footerArea;\r
+       }\r
+\r
+       /**\r
+        * @return the shell\r
+        */\r
+       public Shell getShell() {\r
+               return this.shell;\r
+       }\r
+\r
+       /**\r
+        * @return the index of the selected button\r
+        */\r
+       public int getSelectedButton() {\r
+               return getFooterArea().getSelectedButton();\r
+       }\r
+\r
+       /**\r
+        * @return the selection state of the checkbox\r
+        */\r
+       public boolean getCheckboxValue() {\r
+               return this.footerArea.getCheckBoxValue();\r
+       }\r
+\r
+       /**\r
+        * @return the minimum width of the dialog box\r
+        */\r
+       public int getMinimumWidth() {\r
+               return this.minimumWidth;\r
+       }\r
+\r
+       /**\r
+        * @param minimumWidth the minimum width of the dialog box to set\r
+        */\r
+       public void setMinimumWidth(final int minimumWidth) {\r
+               this.minimumWidth = minimumWidth;\r
+       }\r
+\r
+       /**\r
+        * @return the minimum height of the dialog box\r
+        */\r
+       public int getMinimumHeight() {\r
+               return this.minimumHeight;\r
+       }\r
+\r
+       /**\r
+        * @param minimumHeight the minimum height of the dialog box to set\r
+        */\r
+       public void setMinimumHeight(final int minimumHeight) {\r
+               this.minimumHeight = minimumHeight;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/DialogArea.java b/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/DialogArea.java
new file mode 100644 (file)
index 0000000..3e47693
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *     Eugene Ryzhikov - Author of the Oxbow Project (http://code.google.com/p/oxbow/) - Inspiration\r
+ *******************************************************************************/\r
+package org.mihalis.opal.opalDialog;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * This abstract class if the mother of MessageArea and FooterArea classes\r
+ */\r
+abstract class DialogArea {\r
+       protected final Dialog parent;\r
+       private boolean initialised;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param parent parent dialog\r
+        */\r
+       public DialogArea(final Dialog parent) {\r
+               this.parent = parent;\r
+       }\r
+\r
+       /**\r
+        * Render the content of an area\r
+        */\r
+       abstract void render();\r
+\r
+       /**\r
+        * @return the initialised field\r
+        */\r
+       boolean isInitialised() {\r
+               return this.initialised;\r
+       }\r
+\r
+       /**\r
+        * @param initialised the initialised value to set\r
+        */\r
+       void setInitialised(final boolean initialised) {\r
+               this.initialised = initialised;\r
+       }\r
+\r
+       /**\r
+        * @return the normal font used by the dialog box\r
+        */\r
+       protected Font getNormalFont() {\r
+               return getFont("Segoe UI", 9, SWT.NONE);\r
+       }\r
+\r
+       /**\r
+        * @return the bigger font used by the dialog box\r
+        */\r
+       protected Font getBiggerFont() {\r
+               return getFont("Segoe UI", 11, SWT.NONE);\r
+       }\r
+\r
+       /**\r
+        * Build a font\r
+        * \r
+        * @param name name of the font\r
+        * @param size size of the font\r
+        * @param style style of the font\r
+        * @return the font\r
+        */\r
+       private Font getFont(final String name, final int size, final int style) {\r
+               final Font font = new Font(Display.getCurrent(), name, size, style);\r
+               this.parent.shell.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(font);\r
+                       }\r
+               });\r
+               return font;\r
+       }\r
+\r
+       /**\r
+        * @return the title's color (blue)\r
+        */\r
+       protected Color getTitleColor() {\r
+               final Color color = new Color(Display.getCurrent(), 35, 107, 178);\r
+               this.parent.shell.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(color);\r
+                       }\r
+               });\r
+               return color;\r
+       }\r
+\r
+       /**\r
+        * @return the grey color\r
+        */\r
+       protected Color getGreyColor() {\r
+               final Color color = new Color(Display.getCurrent(), 240, 240, 240);\r
+               this.parent.shell.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(color);\r
+                       }\r
+               });\r
+               return color;\r
+       }\r
+\r
+       /**\r
+        * @return the image "fewer details"\r
+        */\r
+       protected Image getFewerDetailsImage() {\r
+               return loadImage("images/fewerDetails.png");\r
+       }\r
+\r
+       /**\r
+        * @return the image "more details"\r
+        */\r
+       protected Image getMoreDetailsImage() {\r
+               return loadImage("images/moreDetails.png");\r
+       }\r
+\r
+       /**\r
+        * Loads an image\r
+        * \r
+        * @param fileName file name of the image\r
+        * @return the image\r
+        */\r
+       private Image loadImage(final String fileName) {\r
+               final Image image = SWTGraphicUtil.createImage(fileName);\r
+               this.parent.shell.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SWTGraphicUtil.dispose(image);\r
+                       }\r
+               });\r
+               return image;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/FooterArea.java b/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/FooterArea.java
new file mode 100644 (file)
index 0000000..66c7eca
--- /dev/null
@@ -0,0 +1,531 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *     Eugene Ryzhikov - Author of the Oxbow Project (http://code.google.com/p/oxbow/) - Inspiration\r
+ *******************************************************************************/\r
+package org.mihalis.opal.opalDialog;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+\r
+/**\r
+ * Instances of this class are message areas\r
+ */\r
+public class FooterArea extends DialogArea {\r
+       private Image icon;\r
+       private String footerText;\r
+\r
+       private List<String> buttonLabels;\r
+       private int defaultButtonIndex;\r
+\r
+       private int timer;\r
+       private int timerIndexButton;\r
+\r
+       private int selectedButtonIndex;\r
+\r
+       private String collapsedLabelText;\r
+       private String expandedLabelText;\r
+       private boolean expanded;\r
+       private String detailText;\r
+       private boolean details;\r
+       private Button disabledButton;\r
+\r
+       private String checkBoxLabel;\r
+       private boolean checkBoxValue;\r
+\r
+       private Label expandedPanel;\r
+       private Composite composite;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param parent dialog that is composed of this footer area\r
+        */\r
+       public FooterArea(final Dialog parent) {\r
+               super(parent);\r
+               this.selectedButtonIndex = -1;\r
+               this.expandedLabelText = ResourceManager.getLabel(ResourceManager.FEWER_DETAILS);\r
+               this.collapsedLabelText = ResourceManager.getLabel(ResourceManager.MORE_DETAILS);\r
+               this.timer = -1;\r
+               this.timerIndexButton = -1;\r
+       }\r
+\r
+       /**\r
+        * Add a check box\r
+        * \r
+        * @param label label to display\r
+        * @param selection default value of the check box\r
+        * @return this footer area\r
+        */\r
+       public FooterArea addCheckBox(final String label, final boolean selection) {\r
+               this.checkBoxLabel = label;\r
+               this.checkBoxValue = selection;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.OpalDialog.DialogArea#render()\r
+        */\r
+       @Override\r
+       void render() {\r
+               if (!this.isInitialised()) {\r
+                       return;\r
+               }\r
+\r
+               this.createSeparator();\r
+\r
+               this.composite = new Composite(this.parent.shell, SWT.NONE);\r
+               this.composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));\r
+               this.composite.setBackground(this.getGreyColor());\r
+\r
+               int numberOfColumns = this.buttonLabels == null ? 0 : this.buttonLabels.size();\r
+               if (this.details) {\r
+                       numberOfColumns += 2;\r
+               }\r
+\r
+               final GridLayout gridLayout = new GridLayout(numberOfColumns, false);\r
+               gridLayout.marginHeight = gridLayout.marginWidth = 10;\r
+               this.composite.setLayout(gridLayout);\r
+\r
+               if (this.details) {\r
+                       this.createDetails(numberOfColumns);\r
+               }\r
+\r
+               if (this.buttonLabels != null) {\r
+                       this.createButtons();\r
+               }\r
+\r
+               if (this.details && this.parent.getMessageArea().getException() == null && this.expanded) {\r
+                       this.createExpandedPanel(numberOfColumns);\r
+               }\r
+\r
+               if (this.checkBoxLabel != null) {\r
+                       this.createCheckBox(numberOfColumns);\r
+               }\r
+\r
+               if (this.footerText != null) {\r
+                       this.createFooter();\r
+\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Create the buttons\r
+        */\r
+       private void createButtons() {\r
+               Button defaultButton = null;\r
+               for (int i = 0; i < this.buttonLabels.size(); i++) {\r
+                       final Button button = new Button(this.composite, SWT.PUSH);\r
+                       button.setText(this.buttonLabels.get(i));\r
+\r
+                       final GridData gd = new GridData(GridData.END, GridData.CENTER, i == 0, false);\r
+                       gd.minimumWidth = 70;\r
+                       gd.widthHint = 70;\r
+                       button.setLayoutData(gd);\r
+\r
+                       if (i == this.defaultButtonIndex) {\r
+                               defaultButton = button;\r
+                       }\r
+\r
+                       final Integer integer = new Integer(i);\r
+                       button.addSelectionListener(new SelectionAdapter() {\r
+\r
+                               /**\r
+                                * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                                */\r
+                               @Override\r
+                               public void widgetSelected(final SelectionEvent e) {\r
+                                       FooterArea.this.parent.shell.dispose();\r
+                                       FooterArea.this.selectedButtonIndex = integer.intValue();\r
+                               }\r
+\r
+                       });\r
+\r
+                       if (i == this.timerIndexButton && this.timer != -1) {\r
+                               this.disabledButton = button;\r
+                               button.setData(button.getText());\r
+                               button.setText(button.getText() + " (" + this.timer + ")");\r
+                               button.setEnabled(false);\r
+                       }\r
+\r
+               }\r
+\r
+               if (this.timerIndexButton != -1 && this.timer != -1) {\r
+                       Display.getCurrent().timerExec(1000, new Runnable() {\r
+\r
+                               @Override\r
+                               public void run() {\r
+                                       FooterArea.this.timer--;\r
+                                       if (FooterArea.this.disabledButton.isDisposed()) {\r
+                                               return;\r
+                                       }\r
+\r
+                                       if (FooterArea.this.timer == 0) {\r
+                                               FooterArea.this.disabledButton.setText((String) FooterArea.this.disabledButton.getData());\r
+                                               FooterArea.this.disabledButton.setEnabled(true);\r
+                                       } else {\r
+                                               FooterArea.this.disabledButton.setText(FooterArea.this.disabledButton.getData() + " (" + FooterArea.this.timer + ")");\r
+                                               Display.getCurrent().timerExec(1000, this);\r
+                                       }\r
+\r
+                               }\r
+                       });\r
+               }\r
+\r
+               this.parent.shell.setDefaultButton(defaultButton);\r
+       }\r
+\r
+       /**\r
+        * Create the details section\r
+        * \r
+        * @param numberOfColumns\r
+        */\r
+       private void createDetails(final int numberOfColumns) {\r
+               final Label icon = new Label(this.composite, SWT.NONE);\r
+               icon.setBackground(this.getGreyColor());\r
+               icon.setImage(this.isExpanded() ? this.getFewerDetailsImage() : this.getMoreDetailsImage());\r
+               icon.setLayoutData(new GridData(GridData.CENTER, GridData.CENTER, false, false));\r
+\r
+               final Label label = new Label(this.composite, SWT.NONE);\r
+               label.setBackground(this.getGreyColor());\r
+               label.setText(this.isExpanded() ? this.expandedLabelText : this.collapsedLabelText);\r
+               label.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, false, false));\r
+\r
+               final int numberOfColumnsParam = numberOfColumns;\r
+\r
+               final Listener listener = new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               if (FooterArea.this.parent.getMessageArea().getException() != null) {\r
+                                       if (label.getText().equals(FooterArea.this.expandedLabelText)) {\r
+                                               label.setText(FooterArea.this.collapsedLabelText);\r
+                                               icon.setImage(FooterArea.this.getMoreDetailsImage());\r
+                                               FooterArea.this.parent.getMessageArea().hideException();\r
+                                       } else {\r
+                                               label.setText(FooterArea.this.expandedLabelText);\r
+                                               icon.setImage(FooterArea.this.getFewerDetailsImage());\r
+                                               FooterArea.this.parent.getMessageArea().showException();\r
+                                       }\r
+\r
+                               } else {\r
+                                       if (label.getText().equals(FooterArea.this.expandedLabelText)) {\r
+                                               label.setText(FooterArea.this.collapsedLabelText);\r
+                                               icon.setImage(FooterArea.this.getMoreDetailsImage());\r
+                                               FooterArea.this.expandedPanel.dispose();\r
+                                               FooterArea.this.parent.pack();\r
+                                       } else {\r
+                                               label.setText(FooterArea.this.expandedLabelText);\r
+                                               icon.setImage(FooterArea.this.getFewerDetailsImage());\r
+                                               FooterArea.this.createExpandedPanel(numberOfColumnsParam);\r
+                                               FooterArea.this.parent.pack();\r
+                                       }\r
+                               }\r
+                       }\r
+               };\r
+\r
+               label.addListener(SWT.MouseUp, listener);\r
+               icon.addListener(SWT.MouseUp, listener);\r
+       }\r
+\r
+       /**\r
+        * Create a check box\r
+        * \r
+        * @param numberOfColumns\r
+        */\r
+       private void createCheckBox(final int numberOfColumns) {\r
+               final Button button = new Button(this.composite, SWT.CHECK);\r
+               button.setText(this.checkBoxLabel);\r
+               button.setSelection(this.checkBoxValue);\r
+               button.setBackground(this.getGreyColor());\r
+               button.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, true, false, numberOfColumns, 1));\r
+               button.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               FooterArea.this.checkBoxValue = button.getSelection();\r
+                       }\r
+\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Create footer section\r
+        */\r
+       private void createFooter() {\r
+               this.createSeparator();\r
+\r
+               final Composite informationComposite = new Composite(this.parent.shell, SWT.NONE);\r
+               informationComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, false, false));\r
+               informationComposite.setBackground(this.getGreyColor());\r
+\r
+               informationComposite.setLayout(new GridLayout(this.icon == null ? 1 : 2, false));\r
+\r
+               if (this.icon != null) {\r
+                       final Label labelIcon = new Label(informationComposite, SWT.NONE);\r
+                       labelIcon.setBackground(this.getGreyColor());\r
+                       labelIcon.setImage(this.icon);\r
+                       labelIcon.setLayoutData(new GridData(GridData.CENTER, GridData.CENTER, false, false));\r
+               }\r
+               final Label labelText = new Label(informationComposite, SWT.NONE);\r
+               labelText.setBackground(this.getGreyColor());\r
+               labelText.setText(this.footerText);\r
+               labelText.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));\r
+       }\r
+\r
+       /**\r
+        * Create the expanded panel\r
+        * \r
+        * @param numberOfColumns\r
+        */\r
+       private void createExpandedPanel(final int numberOfColumns) {\r
+               this.expandedPanel = new Label(this.composite, SWT.BORDER);\r
+               this.expandedPanel.setText(this.detailText);\r
+               this.expandedPanel.setBackground(this.getGreyColor());\r
+               final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false, numberOfColumns, 1);\r
+               gd.minimumHeight = gd.heightHint = 150;\r
+               this.expandedPanel.setLayoutData(gd);\r
+       }\r
+\r
+       /**\r
+        * Create a separator\r
+        */\r
+       private void createSeparator() {\r
+               final Composite c = new Composite(this.parent.shell, SWT.NONE);\r
+               c.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));\r
+               c.setBackground(this.getGreyColor());\r
+\r
+               final GridLayout gridLayout = new GridLayout(1, false);\r
+               gridLayout.marginHeight = gridLayout.marginWidth = 0;\r
+               c.setLayout(gridLayout);\r
+\r
+               final Label separator = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL);\r
+               separator.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));\r
+\r
+       }\r
+\r
+       // ------------------------------------------- Getters & Setters\r
+\r
+       /**\r
+        * @return the icon\r
+        */\r
+       public Image getIcon() {\r
+               return this.icon;\r
+       }\r
+\r
+       /**\r
+        * @param icon the icon to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setIcon(final Image icon) {\r
+               this.icon = icon;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the text\r
+        */\r
+       public String getFooterText() {\r
+               return this.footerText;\r
+       }\r
+\r
+       /**\r
+        * @param text the text to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setFooterText(final String text) {\r
+               this.footerText = text;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the button labels\r
+        */\r
+       public List<String> getButtonLabels() {\r
+               return this.buttonLabels;\r
+       }\r
+\r
+       /**\r
+        * @param buttonLabels the button labels to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setButtonLabels(final List<String> buttonLabels) {\r
+               this.buttonLabels = buttonLabels;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @param buttonLabels the button labels to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setButtonLabels(final String... buttonLabels) {\r
+               this.buttonLabels = Arrays.asList(buttonLabels);\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the default button index\r
+        */\r
+       public int getDefaultButtonIndex() {\r
+               return this.defaultButtonIndex;\r
+       }\r
+\r
+       /**\r
+        * @param defaultButtonIndex the default button index to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setDefaultButtonIndex(final int defaultButtonIndex) {\r
+               this.defaultButtonIndex = defaultButtonIndex;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the timer value\r
+        */\r
+       public int getTimer() {\r
+               return this.timer;\r
+       }\r
+\r
+       /**\r
+        * @param timer the timer value to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setTimer(final int timer) {\r
+               this.timer = timer;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the timer index button\r
+        */\r
+       public int getTimerIndexButton() {\r
+               return this.timerIndexButton;\r
+       }\r
+\r
+       /**\r
+        * @param timerIndexButton the timer index button to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setTimerIndexButton(final int timerIndexButton) {\r
+               this.timerIndexButton = timerIndexButton;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the selected button\r
+        */\r
+       int getSelectedButton() {\r
+               return this.selectedButtonIndex;\r
+       }\r
+\r
+       /**\r
+        * @return the collapsed label text\r
+        */\r
+       public String getCollapsedLabelText() {\r
+               return this.collapsedLabelText;\r
+       }\r
+\r
+       /**\r
+        * @param collapsedLabelText the collapsed label text to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setCollapsedLabelText(final String collapsedLabelText) {\r
+               this.details = true;\r
+               this.collapsedLabelText = collapsedLabelText;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the expanded label text\r
+        */\r
+       public String getExpandedLabelText() {\r
+               return this.expandedLabelText;\r
+       }\r
+\r
+       /**\r
+        * @param expandedLabelText the expanded label text to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setExpandedLabelText(final String expandedLabelText) {\r
+               this.details = true;\r
+               this.expandedLabelText = expandedLabelText;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the expanded flag\r
+        */\r
+       public boolean isExpanded() {\r
+               return this.expanded;\r
+       }\r
+\r
+       /**\r
+        * @param expanded the expanded flag to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setExpanded(final boolean expanded) {\r
+               this.details = true;\r
+               this.expanded = expanded;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the detail text\r
+        */\r
+       public String getDetailText() {\r
+               return this.detailText;\r
+       }\r
+\r
+       /**\r
+        * @param detailText the detail text to set\r
+        * @return this footer area\r
+        */\r
+       public FooterArea setDetailText(final String detailText) {\r
+               this.details = true;\r
+               this.detailText = detailText;\r
+               this.setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the check box vqlue\r
+        */\r
+       public boolean getCheckBoxValue() {\r
+               return this.checkBoxValue;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/MessageArea.java b/org.tizen.common.externals/src/org/mihalis/opal/opalDialog/MessageArea.java
new file mode 100644 (file)
index 0000000..55cc9e8
--- /dev/null
@@ -0,0 +1,541 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *     Eugene Ryzhikov - Author of the Oxbow Project (http://code.google.com/p/oxbow/) - Inspiration\r
+ *******************************************************************************/\r
+package org.mihalis.opal.opalDialog;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.ProgressBar;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+import org.mihalis.opal.utils.StringUtil;\r
+\r
+/**\r
+ * Instances of this class are message areas\r
+ */\r
+public class MessageArea extends DialogArea {\r
+       // Main composite\r
+       private Composite composite;\r
+\r
+       // Informations for a simple dialog box\r
+       private String title;\r
+       private Image icon;\r
+       private String text;\r
+\r
+       // Informations for a radio choice dialog box\r
+       private int radioChoice;\r
+       private int radioDefaultSelection;\r
+       private String[] radioValues;\r
+\r
+       // Informations for a exception viewer dialog box\r
+       private Throwable exception;\r
+       private Text textException;\r
+\r
+       // Informations for an input dialog box\r
+       private String textBoxValue;\r
+\r
+       // Informations for a choice dialog box\r
+       private int choice;\r
+       private int choiceDefaultSelection;\r
+       private ChoiceItem[] choiceValues;\r
+\r
+       // Informations for a progress bar displayed in a dialog box\r
+       private ProgressBar progressBar;\r
+       private int progressBarMinimumValue;\r
+       private int progressBarMaximumValue;\r
+       private int progressBarValue;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param parent dialog that is composed of this message area\r
+        */\r
+       public MessageArea(final Dialog parent) {\r
+               super(parent);\r
+               this.radioChoice = -1;\r
+               this.choice = -1;\r
+               this.progressBarValue = -1;\r
+       }\r
+\r
+       /**\r
+        * Add a choice\r
+        * \r
+        * @param defaultSelection default selection\r
+        * @param items a list of the choice item\r
+        * @return the current message area\r
+        */\r
+       public MessageArea addChoice(final int defaultSelection, final ChoiceItem... items) {\r
+               setInitialised(true);\r
+               this.choiceDefaultSelection = defaultSelection;\r
+               this.choiceValues = items;\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * Add a choice composed of radio buttons\r
+        * \r
+        * @param defaultSelection default selection\r
+        * @param values values\r
+        * @return the current message area\r
+        */\r
+       public MessageArea addRadioButtons(final int defaultSelection, final String... values) {\r
+               setInitialised(true);\r
+               this.radioDefaultSelection = defaultSelection;\r
+               this.radioValues = values;\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * Add a text box for input\r
+        * \r
+        * @param value defaut value of the textbox\r
+        * @return the current message area\r
+        */\r
+       public MessageArea addTextBox(final String value) {\r
+               setInitialised(true);\r
+               this.textBoxValue = value;\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * Add a progress bar\r
+        * \r
+        * @param mininum minimum value\r
+        * @param maximum maximum value\r
+        * @param value default value\r
+        * @return the current message area\r
+        */\r
+       public MessageArea addProgressBar(final int mininum, final int maximum, final int value) {\r
+               setInitialised(true);\r
+               this.progressBarMinimumValue = mininum;\r
+               this.progressBarMaximumValue = maximum;\r
+               this.progressBarValue = value;\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.OpalDialog.DialogArea#render()\r
+        */\r
+       @Override\r
+       public void render() {\r
+               if (!isInitialised()) {\r
+                       return;\r
+               }\r
+\r
+               this.composite = new Composite(this.parent.shell, SWT.NONE);\r
+               this.composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));\r
+               this.composite.setBackground(this.composite.getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+\r
+               final boolean hasIcon = this.icon != null;\r
+               final boolean hasTitle = !StringUtil.isEmpty(this.title);\r
+               final boolean hasText = !StringUtil.isEmpty(this.text);\r
+               final boolean hasRadio = this.radioValues != null;\r
+               final boolean hasException = this.exception != null;\r
+               final boolean hasTextbox = this.textBoxValue != null;\r
+               final boolean hasChoice = this.choiceValues != null;\r
+               final boolean hasProgressBar = this.progressBarValue != -1;\r
+\r
+               final int numberOfColumns = hasIcon ? 2 : 1;\r
+               int numberOfRows = hasTitle && hasText ? 2 : 1;\r
+\r
+               if (hasRadio) {\r
+                       numberOfRows += this.radioValues.length;\r
+               }\r
+\r
+               if (hasChoice) {\r
+                       numberOfRows += this.choiceValues.length;\r
+               }\r
+\r
+               if (hasException || hasTextbox) {\r
+                       numberOfRows++;\r
+               }\r
+\r
+               if (hasProgressBar) {\r
+                       numberOfRows++;\r
+               }\r
+\r
+               final GridLayout gridLayout = new GridLayout(numberOfColumns, false);\r
+               gridLayout.marginHeight = gridLayout.marginWidth = 0;\r
+               gridLayout.marginRight = 10;\r
+               gridLayout.marginLeft = 10;\r
+               gridLayout.marginTop = 10;\r
+               gridLayout.marginBottom = 10;\r
+               this.composite.setLayout(gridLayout);\r
+\r
+               if (hasIcon) {\r
+                       createIcon(numberOfRows);\r
+               }\r
+\r
+               if (hasTitle) {\r
+                       createTitle(hasIcon);\r
+               }\r
+\r
+               if (hasText) {\r
+                       createText(hasIcon, hasTitle);\r
+               }\r
+\r
+               if (hasRadio) {\r
+                       createRadioButtons();\r
+               }\r
+\r
+               if (hasException) {\r
+                       createTextException();\r
+               }\r
+\r
+               if (hasTextbox) {\r
+                       createTextBox();\r
+               }\r
+\r
+               if (hasChoice) {\r
+                       createChoice();\r
+               }\r
+\r
+               if (hasProgressBar) {\r
+                       createProgressBar();\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Create the icon\r
+        * \r
+        * @param numberOfRows number of rows displayed\r
+        */\r
+       private void createIcon(final int numberOfRows) {\r
+               final Label label = new Label(this.composite, SWT.NONE);\r
+               label.setImage(this.icon);\r
+               label.setBackground(this.composite.getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+               label.setLayoutData(new GridData(GridData.CENTER, GridData.BEGINNING, false, false, 1, numberOfRows));\r
+       }\r
+\r
+       /**\r
+        * Create the title\r
+        * \r
+        * @param hasIcon if <code>true</code> an icon is displayed\r
+        */\r
+       private void createTitle(final boolean hasIcon) {\r
+               final Label label = new Label(this.composite, SWT.NONE);\r
+               label.setText(this.title);\r
+               label.setFont(getBiggerFont());\r
+               label.setForeground(getTitleColor());\r
+               label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));\r
+               final GridData gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false, 1, 1);\r
+\r
+               if (hasIcon) {\r
+                       gd.horizontalIndent = 8;\r
+               } else {\r
+                       gd.horizontalIndent = 10;\r
+                       gd.verticalIndent = 10;\r
+               }\r
+\r
+               label.setLayoutData(gd);\r
+       }\r
+\r
+       /**\r
+        * Create the text\r
+        * \r
+        * @param hasIcon if <code>true</code> an icon is displayed\r
+        * @param hasTitle if <code>true</code> a title is displayed\r
+        */\r
+       private void createText(final boolean hasIcon, final boolean hasTitle) {\r
+               final StyledText label = new StyledText(this.composite, SWT.NONE);\r
+               label.setText("<html><body>" + this.text + "</body></html>");\r
+               SWTGraphicUtil.applyHTMLFormating(label);\r
+               label.setEnabled(false);\r
+               label.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));\r
+               final GridData gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false, 1, 1);\r
+\r
+               if (hasIcon) {\r
+                       gd.horizontalIndent = 8;\r
+               } else {\r
+                       gd.horizontalIndent = 20;\r
+                       if (hasTitle) {\r
+                               gd.verticalIndent = 8;\r
+                       } else {\r
+                               gd.verticalIndent = 20;\r
+                       }\r
+               }\r
+\r
+               label.setLayoutData(gd);\r
+       }\r
+\r
+       /**\r
+        * Create radio buttons\r
+        */\r
+       private void createRadioButtons() {\r
+               for (int i = 0; i < this.radioValues.length; i++) {\r
+                       final Button button = new Button(this.composite, SWT.RADIO);\r
+                       button.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));\r
+                       button.setText(this.radioValues[i]);\r
+\r
+                       final Integer index = new Integer(i);\r
+                       button.addSelectionListener(new SelectionAdapter() {\r
+\r
+                               /**\r
+                                * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                                */\r
+                               @Override\r
+                               public void widgetSelected(final SelectionEvent e) {\r
+                                       if (button.getSelection()) {\r
+                                               MessageArea.this.radioChoice = index.intValue();\r
+                                       }\r
+                               }\r
+\r
+                       });\r
+\r
+                       button.setSelection(i == this.radioDefaultSelection);\r
+                       final GridData gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false, 1, 1);\r
+                       gd.horizontalIndent = 10;\r
+                       button.setLayoutData(gd);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Create the text that displays an exception\r
+        */\r
+       private void createTextException() {\r
+               this.textException = new Text(this.composite, SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);\r
+               this.textException.setText(StringUtil.stackStraceAsString(this.exception));\r
+               this.textException.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));\r
+               final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false, 1, 1);\r
+               gd.minimumHeight = 300;\r
+               this.textException.setLayoutData(gd);\r
+       }\r
+\r
+       /**\r
+        * Create a text box\r
+        */\r
+       private void createTextBox() {\r
+               final Text textbox = new Text(this.composite, SWT.SINGLE | SWT.BORDER);\r
+               textbox.setText(this.textBoxValue);\r
+               textbox.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));\r
+               final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1);\r
+               textbox.setLayoutData(gd);\r
+               textbox.addModifyListener(new ModifyListener() {\r
+\r
+                       @Override\r
+                       public void modifyText(final ModifyEvent e) {\r
+                               MessageArea.this.textBoxValue = textbox.getText();\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Create a choice selection\r
+        */\r
+       private void createChoice() {\r
+               for (int i = 0; i < this.choiceValues.length; i++) {\r
+                       final ChoiceWidget choice = new ChoiceWidget(this.composite, SWT.RADIO);\r
+                       choice.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));\r
+                       choice.setChoiceItem(this.choiceValues[i]);\r
+\r
+                       final Integer index = new Integer(i);\r
+                       choice.addSelectionListener(new SelectionAdapter() {\r
+\r
+                               /**\r
+                                * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                                */\r
+                               @Override\r
+                               public void widgetSelected(final SelectionEvent e) {\r
+                                       MessageArea.this.choice = index.intValue();\r
+                                       MessageArea.this.parent.shell.dispose();\r
+                               }\r
+\r
+                       });\r
+\r
+                       choice.setSelection(i == this.choiceDefaultSelection);\r
+                       final GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false, 1, 1);\r
+                       choice.setLayoutData(gd);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Create a progress bar\r
+        */\r
+       private void createProgressBar() {\r
+               this.progressBar = new ProgressBar(this.composite, SWT.SMOOTH | SWT.HORIZONTAL);\r
+               this.progressBar.setMinimum(this.progressBarMinimumValue);\r
+               this.progressBar.setMaximum(this.progressBarMaximumValue);\r
+               this.progressBar.setSelection(this.progressBarValue);\r
+               this.progressBar.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));\r
+               final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false, 1, 1);\r
+               this.progressBar.setLayoutData(gd);\r
+       }\r
+\r
+       /**\r
+        * Hide the exception panel\r
+        */\r
+       void hideException() {\r
+               this.textException.dispose();\r
+               this.parent.pack();\r
+\r
+       }\r
+\r
+       /**\r
+        * Show the exception panel\r
+        */\r
+       void showException() {\r
+               createTextException();\r
+               this.parent.pack();\r
+       }\r
+\r
+       // ------------------------------------------- Getters & Setters\r
+\r
+       /**\r
+        * @return the title\r
+        */\r
+       public String getTitle() {\r
+               return this.title;\r
+       }\r
+\r
+       /**\r
+        * @param title the title to set\r
+        * @return the current message area\r
+        */\r
+       public MessageArea setTitle(final String title) {\r
+               this.title = title;\r
+               setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the icon\r
+        */\r
+       public Image getIcon() {\r
+               return this.icon;\r
+       }\r
+\r
+       /**\r
+        * @param icon the icon to set\r
+        */\r
+       public MessageArea setIcon(final Image icon) {\r
+               this.icon = icon;\r
+               setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the text\r
+        */\r
+       public String getText() {\r
+               return this.text;\r
+       }\r
+\r
+       /**\r
+        * @param text the text to set\r
+        */\r
+       public MessageArea setText(final String text) {\r
+               this.text = text;\r
+               setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the radio choice\r
+        */\r
+       public int getRadioChoice() {\r
+               return this.radioChoice;\r
+       }\r
+\r
+       /**\r
+        * @return the exception\r
+        */\r
+       public Throwable getException() {\r
+               return this.exception;\r
+       }\r
+\r
+       /**\r
+        * @param exception the exception to set\r
+        * @return\r
+        */\r
+       public MessageArea setException(final Throwable exception) {\r
+               this.exception = exception;\r
+               setInitialised(true);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the choice\r
+        */\r
+       public int getChoice() {\r
+               return this.choice;\r
+       }\r
+\r
+       /**\r
+        * @return the value stored in the text box\r
+        */\r
+       public String getTextBoxValue() {\r
+               return this.textBoxValue;\r
+       }\r
+\r
+       /**\r
+        * @return the progress bar minimum value\r
+        */\r
+       public int getProgressBarMinimumValue() {\r
+               return this.progressBarMinimumValue;\r
+       }\r
+\r
+       /**\r
+        * @param progressBarMinimumValue the progress bar minimum value to set\r
+        */\r
+       public void setProgressBarMinimumValue(final int progressBarMinimumValue) {\r
+               this.progressBarMinimumValue = progressBarMinimumValue;\r
+               if (this.progressBar != null && !this.progressBar.isDisposed()) {\r
+                       this.progressBar.setMinimum(progressBarMinimumValue);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return the progress bar maximum value\r
+        */\r
+       public int getProgressBarMaximumValue() {\r
+               return this.progressBarMaximumValue;\r
+       }\r
+\r
+       /**\r
+        * @param progressBarMaximumValue the progress bar minimum value to set\r
+        */\r
+       public void setProgressBarMaximumValue(final int progressBarMaximumValue) {\r
+               this.progressBarMaximumValue = progressBarMaximumValue;\r
+               if (this.progressBar != null && !this.progressBar.isDisposed()) {\r
+                       this.progressBar.setMaximum(progressBarMaximumValue);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @return the progress bar value\r
+        */\r
+       public int getProgressBarValue() {\r
+               return this.progressBarValue;\r
+       }\r
+\r
+       /**\r
+        * @param progressBarValue the progress bar value to set\r
+        */\r
+       public void setProgressBarValue(final int progressBarValue) {\r
+               this.progressBarValue = progressBarValue;\r
+               if (this.progressBar != null && !this.progressBar.isDisposed()) {\r
+                       this.progressBar.setSelection(progressBarValue);\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/panels/BlurredPanel.java b/org.tizen.common.externals/src/org/mihalis/opal/panels/BlurredPanel.java
new file mode 100644 (file)
index 0000000..4d2b79d
--- /dev/null
@@ -0,0 +1,151 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation \r
+ *******************************************************************************/\r
+package org.mihalis.opal.panels;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are controls located on the top of a shell. They\r
+ * display a blurred version of the content of the shell\r
+ */\r
+public class BlurredPanel {\r
+       private final Shell parent;\r
+       private static final String BLURED_PANEL_KEY = "org.mihalis.opal.Panels.DarkPanel";\r
+       private int radius;\r
+       private Shell panel;\r
+       private Canvas canvas;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent.\r
+        * \r
+        * @param shell a shell that will be the parent of the new instance (cannot\r
+        *            be null)\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the parent has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        */\r
+       public BlurredPanel(final Shell shell) {\r
+               if (shell == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (shell.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+\r
+               this.parent = shell;\r
+               if (shell.getData(BLURED_PANEL_KEY) != null) {\r
+                       throw new IllegalArgumentException("This shell has already an infinite panel attached on it !");\r
+               }\r
+               shell.setData(BLURED_PANEL_KEY, this);\r
+               this.radius = 2;\r
+       }\r
+\r
+       /**\r
+        * Show the blurred panel\r
+        */\r
+       public void show() {\r
+               if (this.parent.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               this.panel = new Shell(this.parent, SWT.APPLICATION_MODAL | SWT.NO_TRIM);\r
+               this.panel.setLayout(new FillLayout());\r
+\r
+               this.panel.addListener(SWT.KeyUp, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               event.doit = false;\r
+                       }\r
+               });\r
+\r
+               this.canvas = new Canvas(this.panel, SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED);\r
+               this.canvas.addPaintListener(new PaintListener() {\r
+\r
+                       @Override\r
+                       public void paintControl(final PaintEvent e) {\r
+                               paintCanvas(e);\r
+                       }\r
+               });\r
+\r
+               this.panel.setBounds(this.panel.getDisplay().map(this.parent, null, this.parent.getClientArea()));\r
+               this.panel.open();\r
+\r
+       }\r
+\r
+       /**\r
+        * Paint the canvas that holds the panel\r
+        * \r
+        * @param e {@link PaintEvent}\r
+        */\r
+       private void paintCanvas(final PaintEvent e) {\r
+               // Paint the panel\r
+               e.gc.drawImage(createBlurredImage(), 0, 0);\r
+       }\r
+\r
+       private Image createBlurredImage() {\r
+               final GC gc = new GC(this.parent);\r
+               final Image image = new Image(this.parent.getDisplay(), this.parent.getSize().x, this.parent.getSize().y);\r
+               gc.copyArea(image, 0, 0);\r
+               gc.dispose();\r
+\r
+               return new Image(this.parent.getDisplay(), SWTGraphicUtil.blur(image.getImageData(), this.radius));\r
+\r
+       }\r
+\r
+       /**\r
+        * Hide the panel\r
+        */\r
+       public void hide() {\r
+               if (this.parent.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               if (this.panel == null || this.panel.isDisposed()) {\r
+                       return;\r
+               }\r
+\r
+               this.panel.dispose();\r
+       }\r
+\r
+       /**\r
+        * @return the radius of the blur effect\r
+        */\r
+       public int getRadius() {\r
+               return this.radius;\r
+       }\r
+\r
+       /**\r
+        * @param radius the radius to set\r
+        */\r
+       public void setRadius(final int radius) {\r
+               this.radius = radius;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/panels/DarkPanel.java b/org.tizen.common.externals/src/org/mihalis/opal/panels/DarkPanel.java
new file mode 100644 (file)
index 0000000..ca681be
--- /dev/null
@@ -0,0 +1,144 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation \r
+ *******************************************************************************/\r
+package org.mihalis.opal.panels;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+\r
+/**\r
+ * Instances of this class are controls located on the top of a shell. They\r
+ * display a dark panel on this shell\r
+ */\r
+public class DarkPanel {\r
+       private final Shell parent;\r
+       private static final String DARK_PANEL_KEY = "org.mihalis.opal.BluredPanel.DarkPanel";\r
+       private int alpha;\r
+       private Shell panel;\r
+       private Canvas canvas;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent.\r
+        * \r
+        * @param shell a shell that will be the parent of the new instance (cannot\r
+        *            be null)\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the parent has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        */\r
+       public DarkPanel(final Shell shell) {\r
+               if (shell == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+\r
+               if (shell.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_INVALID_ARGUMENT);\r
+               }\r
+\r
+               this.parent = shell;\r
+               if (shell.getData(DARK_PANEL_KEY) != null) {\r
+                       throw new IllegalArgumentException("This shell has already an infinite panel attached on it !");\r
+               }\r
+               shell.setData(DARK_PANEL_KEY, this);\r
+               this.alpha = 100;\r
+       }\r
+\r
+       /**\r
+        * Show the dark panel\r
+        */\r
+       public void show() {\r
+               if (this.parent.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               this.panel = new Shell(this.parent, SWT.APPLICATION_MODAL | SWT.NO_TRIM);\r
+               this.panel.setLayout(new FillLayout());\r
+               this.panel.setAlpha(this.alpha);\r
+\r
+               this.panel.addListener(SWT.KeyUp, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               event.doit = false;\r
+                       }\r
+               });\r
+\r
+               this.canvas = new Canvas(this.panel, SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED);\r
+               this.canvas.addPaintListener(new PaintListener() {\r
+\r
+                       @Override\r
+                       public void paintControl(final PaintEvent e) {\r
+                               paintCanvas(e);\r
+                       }\r
+               });\r
+\r
+               this.panel.setBounds(this.panel.getDisplay().map(this.parent, null, this.parent.getClientArea()));\r
+               this.panel.open();\r
+\r
+       }\r
+\r
+       /**\r
+        * Paint the canvas that holds the panel\r
+        * \r
+        * @param e {@link PaintEvent}\r
+        */\r
+       private void paintCanvas(final PaintEvent e) {\r
+               // Paint the panel\r
+               final Rectangle clientArea = ((Canvas) e.widget).getClientArea();\r
+               final GC gc = e.gc;\r
+               gc.setBackground(this.panel.getDisplay().getSystemColor(SWT.COLOR_BLACK));\r
+               gc.fillRectangle(clientArea);\r
+       }\r
+\r
+       /**\r
+        * Hide the dark panel\r
+        */\r
+       public void hide() {\r
+               if (this.parent.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               if (this.panel == null || this.panel.isDisposed()) {\r
+                       return;\r
+               }\r
+\r
+               this.panel.dispose();\r
+       }\r
+\r
+       /**\r
+        * @return the alpha value\r
+        */\r
+       public int getAlpha() {\r
+               return this.alpha;\r
+       }\r
+\r
+       /**\r
+        * @param alpha the alpha to set\r
+        */\r
+       public void setAlpha(final int alpha) {\r
+               this.alpha = alpha;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWContainer.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWContainer.java
new file mode 100644 (file)
index 0000000..17784f6
--- /dev/null
@@ -0,0 +1,45 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.mihalis.opal.preferenceWindow.widgets.PWWidget;\r
+\r
+/**\r
+ * Abstract class for "Containers" (row, group and tab)\r
+ * \r
+ */\r
+public abstract class PWContainer {\r
+\r
+       /**\r
+        * Add a container to the current element\r
+        * \r
+        * @param element element to add\r
+        * @return the container\r
+        */\r
+       public abstract PWContainer add(final PWContainer element);\r
+\r
+       /**\r
+        * Add a widget to the current element\r
+        * \r
+        * @param widget widget to add\r
+        * @return the container\r
+        */\r
+       public abstract PWContainer add(final PWWidget widget);\r
+\r
+       /**\r
+        * Build the content of the container\r
+        * \r
+        * @param parent parent composite\r
+        */\r
+       public abstract void build(final Composite parent);\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWGroup.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWGroup.java
new file mode 100644 (file)
index 0000000..ac0efb4
--- /dev/null
@@ -0,0 +1,169 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.mihalis.opal.preferenceWindow.widgets.PWWidget;\r
+\r
+/**\r
+ * Instances of this class are groups\r
+ */\r
+public class PWGroup extends PWRowGroup {\r
+\r
+       private final String label;\r
+       private final boolean hasBorder;\r
+       private final List<PWRow> children;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param hasBorder if <code>true</code>, the group has a border\r
+        */\r
+       public PWGroup(final boolean hasBorder) {\r
+               this(null, hasBorder);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label label associated to the group\r
+        */\r
+       public PWGroup(final String label) {\r
+               this(label, true);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label label associated to the group\r
+        * @param hasBorder if <code>true</code>, the group has a border\r
+        */\r
+       public PWGroup(final String label, final boolean hasBorder) {\r
+               this.label = label;\r
+               this.hasBorder = hasBorder;\r
+               this.children = new ArrayList<PWRow>();\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWContainer#add(org.mihalis.opal.preferenceWindow.PWContainer)\r
+        */\r
+       @Override\r
+       public PWContainer add(final PWContainer element) {\r
+               if (!(element instanceof PWRow)) {\r
+                       throw new UnsupportedOperationException("Can only add a PWRow.");\r
+               }\r
+               this.children.add((PWRow) element);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWContainer#add(org.mihalis.opal.preferenceWindow.widgets.PWWidget)\r
+        */\r
+       @Override\r
+       public PWContainer add(final PWWidget widget) {\r
+               final PWRow row = new PWRow();\r
+               row.add(widget);\r
+               this.children.add(row);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWContainer#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public void build(final Composite parent) {\r
+               final Composite composite;\r
+               if (this.hasBorder) {\r
+                       composite = new Group(parent, SWT.NONE);\r
+                       if (this.label != null && !this.label.trim().equals("")) {\r
+                               ((Group) composite).setText(this.label);\r
+                       }\r
+               } else {\r
+                       composite = new Composite(parent, SWT.BORDER);\r
+               }\r
+\r
+               final int numCol = computeNumberOfColumns();\r
+\r
+               composite.setLayout(new GridLayout(numCol, false));\r
+               composite.setLayoutData(new GridData(GridData.BEGINNING, GridData.FILL, false, false, this.parentNumberOfColums, 1));\r
+\r
+               for (final PWRow row : this.children) {\r
+                       row.setParentNumberOfColumns(numCol);\r
+                       row.build(composite);\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * @return\r
+        */\r
+       private int computeNumberOfColumns() {\r
+               int numberOfColumns = 1;\r
+               for (final PWRow row : this.children) {\r
+                       numberOfColumns = Math.max(numberOfColumns, row.getNumberOfColums());\r
+               }\r
+               return numberOfColumns;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWRowGroup#checkParent(org.mihalis.opal.preferenceWindow.PWContainer)\r
+        */\r
+       @Override\r
+       protected void checkParent(final PWContainer parent) {\r
+               if (parent instanceof PWTab) {\r
+                       return;\r
+               }\r
+               throw new UnsupportedOperationException("Bad parent, should be only PWTab ");\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWRowGroup#enableOrDisable()\r
+        */\r
+       @Override\r
+       public void enableOrDisable() {\r
+               if (this.enabler == null) {\r
+                       return;\r
+               }\r
+\r
+               final boolean enabled = this.enabler.isEnabled();\r
+               for (final PWRow row : this.children) {\r
+                       enableOrDisable(row, enabled);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Enable or disable a row\r
+        * \r
+        * @param row row to enable or disable\r
+        * @param enabled enable flag\r
+        */\r
+       private void enableOrDisable(final PWRow row, final boolean enabled) {\r
+               for (final PWWidget widget : row.widgets) {\r
+                       final boolean widgetEnable = widget.enableOrDisable();\r
+\r
+                       for (final Control c : widget.getControls()) {\r
+                               if (!c.isDisposed()) {\r
+                                       c.setEnabled(enabled && widgetEnable);\r
+                               }\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWRow.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWRow.java
new file mode 100644 (file)
index 0000000..e38abdc
--- /dev/null
@@ -0,0 +1,142 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.mihalis.opal.preferenceWindow.widgets.PWButton;\r
+import org.mihalis.opal.preferenceWindow.widgets.PWLabel;\r
+import org.mihalis.opal.preferenceWindow.widgets.PWWidget;\r
+\r
+/**\r
+ * Instances of this class are rows\r
+ */\r
+public class PWRow extends PWRowGroup {\r
+       protected final List<PWWidget> widgets;\r
+\r
+       /**\r
+        * Constructor\r
+        */\r
+       public PWRow() {\r
+               this.widgets = new ArrayList<PWWidget>();\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWContainer#add(org.mihalis.opal.preferenceWindow.widgets.PWWidget)\r
+        */\r
+       @Override\r
+       public PWContainer add(final PWWidget widget) {\r
+               this.widgets.add(widget);\r
+               addColumn(widget.getNumberOfColumns());\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWContainer#add(org.mihalis.opal.preferenceWindow.PWContainer)\r
+        */\r
+       @Override\r
+       public PWContainer add(final PWContainer element) {\r
+               if (element instanceof PWRow || element instanceof PWGroup) {\r
+                       return this.parent.add(element);\r
+               } else {\r
+                       throw new UnsupportedOperationException("Can only add a PWGroup or a PWRow.");\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWContainer#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public void build(final Composite parent) {\r
+               final int size = this.widgets.size();\r
+               int columIndex = 0;\r
+               for (int i = 0; i < size; i++) {\r
+                       final PWWidget widget = this.widgets.get(i);\r
+                       final Control control = widget.checkAndBuild(parent);\r
+                       if (control != null && control.getLayoutData() == null) {\r
+                               final int colSpan;\r
+                               final boolean grabExcessSpace;\r
+                               final int alignment;\r
+                               if (size == 1) {\r
+                                       if (widget.isSingleWidget()) {\r
+                                               colSpan = this.parentNumberOfColums;\r
+                                       } else {\r
+                                               colSpan = this.parentNumberOfColums - widget.getNumberOfColumns() + 1;\r
+                                       }\r
+                                       grabExcessSpace = true;\r
+                               } else {\r
+                                       if (i == size - 1) {\r
+                                               colSpan = this.parentNumberOfColums - columIndex;\r
+                                               grabExcessSpace = widget.isGrabExcessSpace();\r
+                                       } else {\r
+                                               colSpan = 1;\r
+                                               grabExcessSpace = widget instanceof PWButton && i == 0 ? true : widget.isGrabExcessSpace();\r
+                                       }\r
+                               }\r
+                               columIndex += widget.getNumberOfColumns();\r
+\r
+                               if (i == 0 && grabExcessSpace && size > 1) {\r
+                                       if (widget instanceof PWLabel || widget instanceof PWButton) {\r
+                                               alignment = GridData.END;\r
+                                       } else {\r
+                                               alignment = GridData.BEGINNING;\r
+                                       }\r
+                               } else {\r
+                                       alignment = widget.getAlignment();\r
+                               }\r
+\r
+                               final GridData gd = new GridData(alignment, GridData.BEGINNING, grabExcessSpace, false, colSpan, 1);\r
+                               gd.horizontalIndent = widget.getIndent();\r
+                               gd.widthHint = widget.getWidth();\r
+                               if (widget.getHeight() != -1) {\r
+                                       gd.heightHint = widget.getHeight();\r
+                               }\r
+                               control.setLayoutData(gd);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWRowGroup#checkParent(org.mihalis.opal.preferenceWindow.PWContainer)\r
+        */\r
+       @Override\r
+       protected void checkParent(final PWContainer parent) {\r
+               if (parent instanceof PWTab || parent instanceof PWGroup) {\r
+                       return;\r
+               }\r
+               throw new UnsupportedOperationException("Bad parent, should be only PWTab or PWGroup");\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWRowGroup#enableOrDisable()\r
+        */\r
+       @Override\r
+       public void enableOrDisable() {\r
+               if (this.enabler == null) {\r
+                       return;\r
+               }\r
+\r
+               final boolean enabled = this.enabler.isEnabled();\r
+               for (final PWWidget widget : this.widgets) {\r
+                       final boolean widgetEnable = widget.enableOrDisable();\r
+                       for (final Control c : widget.getControls()) {\r
+                               if (!c.isDisposed()) {\r
+                                       c.setEnabled(enabled && widgetEnable);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWRowGroup.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWRowGroup.java
new file mode 100644 (file)
index 0000000..63674bc
--- /dev/null
@@ -0,0 +1,79 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow;\r
+\r
+import org.mihalis.opal.preferenceWindow.enabler.Enabler;\r
+\r
+/**\r
+ * Abstract class for both row and groups\r
+ */\r
+public abstract class PWRowGroup extends PWContainer {\r
+\r
+       protected int numberOfColumns;\r
+       protected int parentNumberOfColums;\r
+       protected PWContainer parent;\r
+       protected Enabler enabler;\r
+\r
+       /**\r
+        * Check if the parent is compatible with the object\r
+        * \r
+        * @param parent parent to check\r
+        * @throws UnsupportedOperationException if the parent is not compatible\r
+        *             with the object\r
+        */\r
+       protected abstract void checkParent(PWContainer parent);\r
+\r
+       /**\r
+        * Enables or disables all elements stored in this group or row\r
+        */\r
+       public abstract void enableOrDisable();\r
+\r
+       /**\r
+        * Add a column to the current element\r
+        * \r
+        * @param number number of column to add\r
+        */\r
+       public void addColumn(final int number) {\r
+               this.numberOfColumns += number;\r
+       }\r
+\r
+       /**\r
+        * @return the number of columns of this group or row\r
+        */\r
+       public int getNumberOfColums() {\r
+               return this.numberOfColumns;\r
+       }\r
+\r
+       /**\r
+        * @param enabler the enabler to set\r
+        */\r
+       public PWRowGroup setEnabler(final Enabler enabler) {\r
+               this.enabler = enabler;\r
+               this.enabler.injectRowGroup(this);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @param parent the parent to set\r
+        */\r
+       public void setParent(final PWContainer parent) {\r
+               checkParent(parent);\r
+               this.parent = parent;\r
+       }\r
+\r
+       /**\r
+        * @param numberOfColumns the number of columns of the parent\r
+        */\r
+       public void setParentNumberOfColumns(final int numberOfColumns) {\r
+               this.parentNumberOfColums = numberOfColumns;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWTab.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWTab.java
new file mode 100644 (file)
index 0000000..03fc554
--- /dev/null
@@ -0,0 +1,111 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.mihalis.opal.preferenceWindow.widgets.PWWidget;\r
+\r
+/**\r
+ * Instance of this class are tabs\r
+ * \r
+ */\r
+public class PWTab extends PWContainer {\r
+       private final Image image;\r
+       private final String text;\r
+       private final List<PWRowGroup> children;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param image image associated to the tab\r
+        * @param text text associated to the tab\r
+        */\r
+       PWTab(final Image image, final String text) {\r
+               this.image = image;\r
+               this.text = text;\r
+               this.children = new ArrayList<PWRowGroup>();\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWContainer#add(org.mihalis.opal.preferenceWindow.PWContainer)\r
+        */\r
+       @Override\r
+       public PWContainer add(final PWContainer element) {\r
+               if (!(element instanceof PWGroup) && !(element instanceof PWRow)) {\r
+                       throw new UnsupportedOperationException("Can only add a PWGroup or a PWRow.");\r
+               }\r
+               ((PWRowGroup) element).setParent(this);\r
+               this.children.add((PWRowGroup) element);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWContainer#add(org.mihalis.opal.preferenceWindow.widgets.PWWidget)\r
+        */\r
+       @Override\r
+       public PWContainer add(final PWWidget widget) {\r
+               final PWRow row = new PWRow();\r
+               row.setParent(this);\r
+               row.add(widget);\r
+               this.children.add(row);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.PWContainer#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public void build(final Composite parent) {\r
+               final int numberOfColumns = computeNumberOfColums();\r
+               parent.setLayout(new GridLayout(numberOfColumns, false));\r
+\r
+               for (final PWRowGroup rowGroup : this.children) {\r
+                       rowGroup.setParentNumberOfColumns(numberOfColumns);\r
+                       rowGroup.build(parent);\r
+               }\r
+\r
+               PreferenceWindow.getInstance().fireEnablers();\r
+\r
+       }\r
+\r
+       /**\r
+        * @return the total number of columns in this tab\r
+        */\r
+       private int computeNumberOfColums() {\r
+               int numberOfColumns = 1;\r
+               for (final PWRowGroup rowGroup : this.children) {\r
+                       if (rowGroup instanceof PWRow) {\r
+                               numberOfColumns = Math.max(numberOfColumns, rowGroup.getNumberOfColums());\r
+                       }\r
+               }\r
+               return numberOfColumns;\r
+       }\r
+\r
+       /**\r
+        * @return the image associate to this tab\r
+        */\r
+       public Image getImage() {\r
+               return this.image;\r
+       }\r
+\r
+       /**\r
+        * @return the text associated to this tab\r
+        */\r
+       public String getText() {\r
+               return this.text;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWTabContainer.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PWTabContainer.java
new file mode 100644 (file)
index 0000000..8bfe14c
--- /dev/null
@@ -0,0 +1,228 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.flatButton.FlatButton;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are a container that allows the user to select a tab\r
+ */\r
+class PWTabContainer extends Composite {\r
+\r
+    private final List<PWTab> tabs;\r
+    private Composite container;\r
+    private Image oldButtonContainerImage;\r
+    private final List<FlatButton> buttons;\r
+    private Composite buttonContainer;\r
+\r
+    /**\r
+     * Constructor\r
+     * \r
+     * @param parent parent composite\r
+     * @param style style (not used)\r
+     * @param tabs list of tabs\r
+     */\r
+    PWTabContainer(final Composite parent, final int style, final List<PWTab> tabs) {\r
+        super(parent, style);\r
+        this.tabs = new ArrayList<PWTab>();\r
+        this.tabs.addAll(tabs);\r
+\r
+        this.buttons = new ArrayList<FlatButton>();\r
+\r
+        final GridLayout gridLayout = new GridLayout(2, false);\r
+        gridLayout.marginWidth = gridLayout.marginHeight = 0;\r
+        gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;\r
+        setLayout(gridLayout);\r
+\r
+    }\r
+\r
+    /**\r
+     * Build the container\r
+     */\r
+    void build() {\r
+        build(null);\r
+    }\r
+    \r
+    void build(Color selectedTabColor) {\r
+        \r
+        createButtonsContainer();\r
+        createButtons(selectedTabColor);\r
+        createContentContainer();\r
+\r
+        select(0);\r
+    }\r
+\r
+    /**\r
+     * Create the buttons container\r
+     */\r
+    private void createButtonsContainer() {\r
+        createContainer();\r
+        createButtonsContainerBackground();\r
+\r
+    }\r
+\r
+    /**\r
+     * Create the container\r
+     */\r
+    private void createContainer() {\r
+        this.buttonContainer = new Composite(this, SWT.NONE);\r
+        final GridData buttonContainerGridData = new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1);\r
+        //buttonContainerGridData.heightHint = 63; // Original size (32x32)\r
+        //buttonContainerGridData.heightHint = 79; // Tizen fit size (48x48)\r
+        this.buttonContainer.setLayoutData(buttonContainerGridData);\r
+\r
+        this.buttonContainer.setBackground(getDisplay().getSystemColor(SWT.COLOR_WHITE));\r
+\r
+        final GridLayout gridLayout = new GridLayout(this.tabs.size(), false);\r
+        gridLayout.marginWidth = gridLayout.marginHeight = 0;\r
+        gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;\r
+        gridLayout.marginBottom = 2;\r
+        this.buttonContainer.setLayout(gridLayout);\r
+    }\r
+\r
+    /**\r
+     * Create the background of the container\r
+     */\r
+    private void createButtonsContainerBackground() {\r
+        this.buttonContainer.addListener(SWT.Resize, new Listener() {\r
+\r
+            @Override\r
+            public void handleEvent(final Event event) {\r
+                final Rectangle rect = PWTabContainer.this.buttonContainer.getClientArea();\r
+                final Image image = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height));\r
+                final GC gc = new GC(image);\r
+                final Color grey = new Color(getDisplay(), 204, 204, 204);\r
+                gc.setForeground(grey);\r
+                gc.drawLine(0, rect.height - 1, rect.width, rect.height - 1);\r
+                grey.dispose();\r
+                gc.dispose();\r
+                PWTabContainer.this.buttonContainer.setBackgroundImage(image);\r
+                if (PWTabContainer.this.oldButtonContainerImage != null) {\r
+                    PWTabContainer.this.oldButtonContainerImage.dispose();\r
+                }\r
+                PWTabContainer.this.oldButtonContainerImage = image;\r
+\r
+            }\r
+        });\r
+        SWTGraphicUtil.dispose(this.buttonContainer, this.oldButtonContainerImage);\r
+    }\r
+\r
+//    /**\r
+//     * Create the buttons\r
+//     */\r
+//    private void createButtons() {\r
+//        createButtons(null);\r
+//    }\r
+    \r
+    private void createButtons(Color selectedTabColor) {\r
+        for (int i = 0; i < this.tabs.size(); i++) {\r
+            final PWTab tab = this.tabs.get(i);\r
+            final FlatButton button = new FlatButton(this.buttonContainer, SWT.NONE);\r
+            button.setText(tab.getText());\r
+            button.setImage(tab.getImage());\r
+            \r
+            if(selectedTabColor != null) {\r
+                button.setSelectedColor(selectedTabColor);\r
+            }\r
+            SWTGraphicUtil.dispose(button, tab.getImage());\r
+\r
+            final GridData gd;\r
+            if (i == this.tabs.size() - 1) {\r
+                gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, true, false);\r
+            } else {\r
+                gd = new GridData(GridData.BEGINNING, GridData.BEGINNING, false, false);\r
+            }\r
+            if (i == 0) {\r
+                gd.horizontalIndent = 5;\r
+            }\r
+            gd.widthHint = 75;\r
+            button.setLayoutData(gd);\r
+\r
+            final int index = i;\r
+            button.addSelectionListener(new SelectionAdapter() {\r
+\r
+                /**\r
+                 * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                 */\r
+                @Override\r
+                public void widgetSelected(final SelectionEvent e) {\r
+                    select(index);\r
+                }\r
+\r
+            });\r
+\r
+            this.buttons.add(button);\r
+\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Select a given button\r
+     * \r
+     * @param index index of the selected button\r
+     */\r
+    private void select(final int index) {\r
+        for (final Control c : this.container.getChildren()) {\r
+            c.dispose();\r
+        }\r
+\r
+        this.tabs.get(index).build(this.container);\r
+        this.container.layout();\r
+\r
+        for (int i = 0; i < this.buttons.size(); i++) {\r
+            this.buttons.get(i).setSelection(i == index);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Create the content container, ie the composite that will contain all\r
+     * widgets\r
+     */\r
+    private void createContentContainer() {\r
+        this.container = new Composite(this, SWT.NONE);\r
+        final GridData tempContainer = new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1);\r
+        \r
+        int defaultSize = 350;\r
+        int notebookSize = 280;\r
+        \r
+        //tempContainer.widthHint = 700;\r
+        tempContainer.heightHint = defaultSize;\r
+        \r
+        Rectangle bounds = Display.getCurrent().getBounds();\r
+        if (bounds.height <= (768 + defaultSize - notebookSize)) {\r
+            tempContainer.heightHint = notebookSize; // 280px is fitted on 768px display\r
+        }\r
+        \r
+        this.container.setLayoutData(tempContainer);\r
+    }\r
+\r
+    public Composite getContainer() {\r
+        return this.container;\r
+    }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PreferenceWindow.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/PreferenceWindow.java
new file mode 100644 (file)
index 0000000..01de51e
--- /dev/null
@@ -0,0 +1,306 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.mihalis.opal.preferenceWindow.widgets.PWWidget;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * This class is a preference window\r
+ * \r
+ */\r
+public class PreferenceWindow {\r
+       private final Map<String, ValueAndAssociatedWidgets> values;\r
+       private final List<PWTab> tabs;\r
+       private final Shell parentShell;\r
+       private boolean returnedValue;\r
+       private Shell shell;\r
+       private static PreferenceWindow instance;\r
+       \r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param parent parent shell (may be null)\r
+        * @param values a map that contains all values that will be displayed in\r
+        *            widgets\r
+        */\r
+       private PreferenceWindow(final Shell parent, final Map<String, Object> values) {\r
+               this.parentShell = parent;\r
+               this.values = new HashMap<String, ValueAndAssociatedWidgets>(values.size());\r
+\r
+               for (final String key : values.keySet()) {\r
+                       this.values.put(key, new ValueAndAssociatedWidgets(values.get(key)));\r
+               }\r
+\r
+               this.tabs = new ArrayList<PWTab>();\r
+       }\r
+\r
+       /**\r
+        * Create a preference window (a singleton)\r
+        * \r
+        * @param parent parent shell (may be null)\r
+        * @param values a map that contains all values that will be displayed in\r
+        *            widgets\r
+        * @return\r
+        */\r
+       public static PreferenceWindow create(final Shell parent, final Map<String, Object> values) {\r
+               instance = new PreferenceWindow(parent, values);\r
+               return instance;\r
+       }\r
+\r
+       /**\r
+        * Create a preference window (a singleton)\r
+        * \r
+        * @param values a map that contains all values that will be displayed in\r
+        *            widgets\r
+        * @return\r
+        */\r
+       public static PreferenceWindow create(final Map<String, Object> values) {\r
+               instance = new PreferenceWindow(null, values);\r
+               return instance;\r
+       }\r
+\r
+       /**\r
+        * @return an instance of the preference window\r
+        */\r
+       public static PreferenceWindow getInstance() {\r
+               if (instance == null) {\r
+                       throw new NullPointerException("The instance of PreferenceWindow has not yet been created or has been destroyed.");\r
+               }\r
+               return instance;\r
+       }\r
+\r
+       /**\r
+        * Add a tab to the preference window\r
+        * \r
+        * @param image image associated to the tab\r
+        * @param text text associated to the image\r
+        * @return the\r
+        */\r
+       public PWTab addTab(final Image image, final String text) {\r
+               final PWTab tab = new PWTab(image, text);\r
+               this.tabs.add(tab);\r
+               return tab;\r
+       }\r
+\r
+       /**\r
+        * Add a widget that is linked to a given property\r
+        * \r
+        * @param propertyKey the property\r
+        * @param widget the widget\r
+        */\r
+       public void addWidgetLinkedTo(final String propertyKey, final PWWidget widget) {\r
+               if (!this.values.containsKey(propertyKey)) {\r
+                       this.values.put(propertyKey, new ValueAndAssociatedWidgets(null));\r
+               }\r
+               this.values.get(propertyKey).addWidget(widget);\r
+       }\r
+\r
+       /**\r
+        * Add a row group that is linked to a given property\r
+        * \r
+        * @param propertyKey the property\r
+        * @param rowGroup the widget\r
+        */\r
+       public void addRowGroupLinkedTo(final String propertyKey, final PWRowGroup rowGroup) {\r
+               if (!this.values.containsKey(propertyKey)) {\r
+                       this.values.put(propertyKey, new ValueAndAssociatedWidgets(null));\r
+               }\r
+               this.values.get(propertyKey).addRowGroup(rowGroup);\r
+       }\r
+\r
+       /**\r
+        * Open the preference window\r
+        * \r
+        * @return <code>true</code> if the user pressed on the Ok button,\r
+        *         <code>false</code> if the user pressed on the Cancel button\r
+        */\r
+       public boolean open() {\r
+               if (this.parentShell == null) {\r
+                       this.shell = new Shell(SWT.SHELL_TRIM);\r
+               } else {\r
+                       this.shell = new Shell(instance.parentShell, SWT.SHELL_TRIM);\r
+               }\r
+\r
+               this.shell.addListener(SWT.Dispose, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               instance = null;\r
+                       }\r
+               });\r
+\r
+               buildShell();\r
+               openShell();\r
+\r
+               return this.returnedValue;\r
+       }\r
+\r
+       /**\r
+        * Builds the shell\r
+        */\r
+       private void buildShell() {\r
+               this.shell.setText(ResourceManager.getLabel(ResourceManager.PREFERENCES));\r
+               final GridLayout gridLayout = new GridLayout(2, false);\r
+               gridLayout.marginWidth = gridLayout.marginHeight = 0;\r
+               gridLayout.horizontalSpacing = gridLayout.verticalSpacing = 0;\r
+               this.shell.setLayout(gridLayout);\r
+               final PWTabContainer container = new PWTabContainer(this.shell, SWT.NONE, this.tabs);\r
+               container.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));\r
+               container.build();\r
+\r
+               final Label sep = new Label(this.shell, SWT.SEPARATOR | SWT.HORIZONTAL);\r
+               sep.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));\r
+\r
+               buildButtons();\r
+\r
+       }\r
+\r
+    /**\r
+     * Builds the Tabs for inner composite\r
+     * \r
+     * @author Jihoon Song {@literal <jihoon80.song@samsung.com>} (S-Core)\r
+     */\r
+    public void buildTabs(Composite parent) {\r
+        buildTabs(parent, null);\r
+    }\r
+    \r
+    public void buildTabs(Composite parent, Color selectedTabColor) {\r
+        final PWTabContainer container = new PWTabContainer(parent, SWT.BORDER, this.tabs);\r
+        container.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));\r
+        container.build(selectedTabColor);\r
+    }\r
+\r
+       /**\r
+        * Builds the buttons\r
+        */\r
+       private void buildButtons() {\r
+               final Button buttonOK = new Button(this.shell, SWT.PUSH);\r
+               buttonOK.setText(ResourceManager.getLabel(ResourceManager.OK));\r
+               final GridData gridDataOk = new GridData(GridData.END, GridData.END, true, false);\r
+               gridDataOk.widthHint = 100;\r
+               buttonOK.setLayoutData(gridDataOk);\r
+               buttonOK.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               PreferenceWindow.this.returnedValue = true;\r
+                               PreferenceWindow.this.shell.dispose();\r
+                       }\r
+\r
+               });\r
+               this.shell.setDefaultButton(buttonOK);\r
+\r
+               final Button buttonCancel = new Button(this.shell, SWT.PUSH);\r
+               buttonCancel.setText(ResourceManager.getLabel(ResourceManager.CANCEL));\r
+               final GridData gridDataCancel = new GridData(GridData.BEGINNING, GridData.END, false, false);\r
+               gridDataCancel.widthHint = 100;\r
+               buttonCancel.setLayoutData(gridDataCancel);\r
+               buttonCancel.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               PreferenceWindow.this.returnedValue = false;\r
+                               PreferenceWindow.this.shell.dispose();\r
+                       }\r
+\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Open the shell\r
+        */\r
+       private void openShell() {\r
+               this.shell.pack();\r
+               this.shell.open();\r
+               SWTGraphicUtil.centerShell(this.shell);\r
+\r
+               while (!this.shell.isDisposed()) {\r
+                       if (!this.shell.getDisplay().readAndDispatch()) {\r
+                               this.shell.getDisplay().sleep();\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Fire all enablers\r
+        */\r
+       public void fireEnablers() {\r
+               for (final String key : this.values.keySet()) {\r
+                       this.values.get(key).fireValueChanged();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @param key\r
+        * @return the value associated to the <i>key</i>\r
+        */\r
+       public Object getValueFor(final String key) {\r
+               if (this.values.containsKey(key)) {\r
+                       return this.values.get(key).getValue();\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * @return the list of all values\r
+        */\r
+       public Map<String, Object> getValues() {\r
+               final Map<String, Object> returnedValues = new HashMap<String, Object>();\r
+               for (final String key : this.values.keySet()) {\r
+                       returnedValues.put(key, this.values.get(key).getValue());\r
+               }\r
+               return returnedValues;\r
+       }\r
+\r
+       /**\r
+        * Store a value associated to the key\r
+        * \r
+        * @param key\r
+        * @param value\r
+        */\r
+       public void setValue(final String key, final Object value) {\r
+               if (this.values.containsKey(key)) {\r
+                       this.values.get(key).setValue(value);\r
+               } else {\r
+                       this.values.put(key, new ValueAndAssociatedWidgets(value));\r
+               }\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/ValueAndAssociatedWidgets.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/ValueAndAssociatedWidgets.java
new file mode 100644 (file)
index 0000000..5d13736
--- /dev/null
@@ -0,0 +1,79 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.mihalis.opal.preferenceWindow.widgets.PWWidget;\r
+\r
+/**\r
+ * This POJO contains a value a list of widgets that depends on a given property\r
+ * \r
+ */\r
+class ValueAndAssociatedWidgets {\r
+       private Object value;\r
+       private final List<PWWidget> widgets;\r
+       private final List<PWRowGroup> rowGroups;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param value associated value\r
+        */\r
+       ValueAndAssociatedWidgets(final Object value) {\r
+               this.value = value;\r
+               this.widgets = new ArrayList<PWWidget>();\r
+               this.rowGroups = new ArrayList<PWRowGroup>();\r
+       }\r
+\r
+       /**\r
+        * @param widget dependant widget\r
+        */\r
+       void addWidget(final PWWidget widget) {\r
+               this.widgets.add(widget);\r
+       }\r
+\r
+       /**\r
+        * @param rowGroup dependant row or group\r
+        */\r
+       void addRowGroup(final PWRowGroup rowGroup) {\r
+               this.rowGroups.add(rowGroup);\r
+       }\r
+\r
+       /**\r
+        * @return the value stored in the instance\r
+        */\r
+       Object getValue() {\r
+               return this.value;\r
+       }\r
+\r
+       /**\r
+        * @param value new value stored in this instance\r
+        */\r
+       void setValue(final Object value) {\r
+               this.value = value;\r
+               fireValueChanged();\r
+       }\r
+\r
+       /**\r
+        * Fire events when the value has changed\r
+        */\r
+       void fireValueChanged() {\r
+               for (final PWRowGroup rowGroup : this.rowGroups) {\r
+                       rowGroup.enableOrDisable();\r
+               }\r
+\r
+               for (final PWWidget widget : this.widgets) {\r
+                       widget.enableOrDisable();\r
+               }\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfEquals.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfEquals.java
new file mode 100644 (file)
index 0000000..b29db9d
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.enabler;\r
+\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * This enabler is used to enable a widget if a property is equal to a given\r
+ * value\r
+ */\r
+public class EnabledIfEquals extends Enabler {\r
+       private final Object value;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param prop property to evaluate\r
+        * @param value condition value\r
+        */\r
+       public EnabledIfEquals(final String prop, final Object value) {\r
+               super(prop);\r
+               this.value = value;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.enabler.Enabler#isEnabled()\r
+        */\r
+       @Override\r
+       public boolean isEnabled() {\r
+               final Object propValue = PreferenceWindow.getInstance().getValueFor(this.prop);\r
+               if (this.value == null) {\r
+                       return propValue == null;\r
+               }\r
+               return this.value.equals(propValue);\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfNotEquals.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfNotEquals.java
new file mode 100644 (file)
index 0000000..7f4e9c1
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.enabler;\r
+\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * This enabler is used to enable a widget if a property is not equal to a given\r
+ * value\r
+ */\r
+public class EnabledIfNotEquals extends Enabler {\r
+       private final Object value;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param prop property to evaluate\r
+        * @param value condition value\r
+        */\r
+       public EnabledIfNotEquals(final String prop, final Object value) {\r
+               super(prop);\r
+               this.value = value;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.enabler.Enabler#isEnabled()\r
+        */\r
+       @Override\r
+       public boolean isEnabled() {\r
+               final Object propValue = PreferenceWindow.getInstance().getValueFor(this.prop);\r
+               if (this.value == null) {\r
+                       return propValue == null;\r
+               }\r
+               return !this.value.equals(propValue);\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfTrue.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/EnabledIfTrue.java
new file mode 100644 (file)
index 0000000..969e2c5
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.enabler;\r
+\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * This enabler is used to enable a widget if a boolean property is true\r
+ */\r
+public class EnabledIfTrue extends Enabler {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param prop boolean property\r
+        */\r
+       public EnabledIfTrue(final String prop) {\r
+               super(prop);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.enabler.Enabler#isEnabled()\r
+        */\r
+       @Override\r
+       public boolean isEnabled() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(this.prop);\r
+\r
+               if (value != null && !(value instanceof Boolean)) {\r
+                       throw new UnsupportedOperationException("Impossible to evaluate [" + this.prop + "] because it is not a Boolean !");\r
+               }\r
+\r
+               if (value == null) {\r
+                       return true;\r
+               }\r
+\r
+               return ((Boolean) value).booleanValue();\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/Enabler.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/enabler/Enabler.java
new file mode 100644 (file)
index 0000000..3b0e04a
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.enabler;\r
+\r
+import org.mihalis.opal.preferenceWindow.PWRowGroup;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+import org.mihalis.opal.preferenceWindow.widgets.PWWidget;\r
+\r
+/**\r
+ * This is the abstract class of all Enablers. An enabler is an object used to\r
+ * enable or disable a widget depending on a value of a stored property.\r
+ */\r
+public abstract class Enabler {\r
+\r
+       protected String prop;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param prop property linked to the enabler.\r
+        */\r
+       public Enabler(final String prop) {\r
+               this.prop = prop;\r
+       }\r
+\r
+       /**\r
+        * @return the evaluation condition\r
+        */\r
+       public abstract boolean isEnabled();\r
+\r
+       /**\r
+        * Link a widget to the enabler\r
+        * \r
+        * @param widget widget to link\r
+        */\r
+       public void injectWidget(final PWWidget widget) {\r
+               PreferenceWindow.getInstance().addWidgetLinkedTo(this.prop, widget);\r
+       }\r
+\r
+       /**\r
+        * Link a row or a group to the enabler\r
+        * \r
+        * @param rowGroup RowGroup to link\r
+        */\r
+       public void injectRowGroup(final PWRowGroup rowGroup) {\r
+               PreferenceWindow.getInstance().addRowGroupLinkedTo(this.prop, rowGroup);\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWButton.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWButton.java
new file mode 100644 (file)
index 0000000..4762b80
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+\r
+/**\r
+ * Instances of this class are buttons\r
+ * \r
+ */\r
+public class PWButton extends PWWidget {\r
+       private final SelectionListener listener;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param listener selection listener\r
+        */\r
+       public PWButton(final String label, final SelectionListener listener) {\r
+               super(label, null, 1, true);\r
+               this.listener = listener;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               final Button button = new Button(parent, SWT.PUSH);\r
+               addControl(button);\r
+               if (getLabel() == null) {\r
+                       throw new UnsupportedOperationException("You need to set a label for a button");\r
+               } else {\r
+                       button.setText(getLabel());\r
+               }\r
+               if (this.listener != null) {\r
+                       button.addSelectionListener(this.listener);\r
+               }\r
+\r
+               return button;\r
+\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWCheckbox.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWCheckbox.java
new file mode 100644 (file)
index 0000000..8dc7f36
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are checkboxes\r
+ */\r
+public class PWCheckbox extends PWWidget {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWCheckbox(final String label, final String propertyKey) {\r
+               super(label, propertyKey, 1, true);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               if (getLabel() == null) {\r
+                       throw new UnsupportedOperationException("Please specify a label for a checkbox");\r
+               }\r
+               final Button button = new Button(parent, SWT.CHECK);\r
+               addControl(button);\r
+               button.setText(getLabel());\r
+               final boolean originalSelection = (Boolean) PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               button.setSelection(originalSelection);\r
+\r
+               button.addSelectionListener(new SelectionAdapter() {\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               PreferenceWindow.getInstance().setValue(getPropertyKey(), button.getSelection());\r
+                       }\r
+               });\r
+               return button;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), new Boolean(false));\r
+               } else {\r
+                       if (!(value instanceof Boolean)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a Boolean because it is associated to a checkbox");\r
+                       }\r
+               }\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWChooser.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWChooser.java
new file mode 100644 (file)
index 0000000..318215a
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+\r
+/**\r
+ * Abstract class for chooser widgets\r
+ * \r
+ */\r
+public abstract class PWChooser extends PWWidget {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWChooser(final String label, final String propertyKey) {\r
+               super(label, propertyKey, 3, false);\r
+               setGrabExcessSpace(false);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               final Label label = new Label(parent, SWT.NONE);\r
+\r
+               if (getLabel() == null) {\r
+                       throw new UnsupportedOperationException("You need to set a label for a directory or a dialog chooser");\r
+               } else {\r
+                       label.setText(getLabel());\r
+               }\r
+               addControl(label);\r
+               final GridData labelGridData = new GridData(GridData.END, GridData.BEGINNING, false, false);\r
+               labelGridData.horizontalIndent = getIndent();\r
+               label.setLayoutData(labelGridData);\r
+\r
+               final Text text = new Text(parent, SWT.BORDER | SWT.READ_ONLY);\r
+               addControl(text);\r
+               final GridData textGridData = new GridData(GridData.FILL, GridData.BEGINNING, true, false);\r
+               text.setLayoutData(textGridData);\r
+\r
+               final Button button = new Button(parent, SWT.PUSH);\r
+               addControl(button);\r
+               final GridData buttonGridData = new GridData(GridData.FILL, GridData.BEGINNING, false, false);\r
+               buttonGridData.widthHint = 150;\r
+               button.setText(ResourceManager.getLabel(ResourceManager.CHOOSE) + "...");\r
+               button.setLayoutData(buttonGridData);\r
+\r
+               setButtonAction(text, button);\r
+\r
+               return button;\r
+\r
+       }\r
+\r
+       /**\r
+        * Code executed when the user presses the button\r
+        * \r
+        * @param text text box\r
+        * @param button associated button\r
+        */\r
+       protected abstract void setButtonAction(Text text, Button button);\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWColorChooser.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWColorChooser.java
new file mode 100644 (file)
index 0000000..0d3b1b3
--- /dev/null
@@ -0,0 +1,133 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.ColorDialog;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are used to select a color\r
+ * \r
+ */\r
+public class PWColorChooser extends PWWidget {\r
+\r
+       private Color color;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWColorChooser(final String label, final String propertyKey) {\r
+               super(label, propertyKey, label == null ? 1 : 2, false);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               final RGB rgb = (RGB) PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+\r
+               if (rgb == null) {\r
+                       this.color = Display.getDefault().getSystemColor(SWT.COLOR_WHITE);\r
+               } else {\r
+                       this.color = new Color(Display.getDefault(), rgb);\r
+               }\r
+\r
+               buildLabel(parent, GridData.CENTER);\r
+               final Button button = new Button(parent, SWT.PUSH);\r
+               addControl(button);\r
+\r
+               button.addListener(SWT.Resize, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               drawButton(button);\r
+                       }\r
+               });\r
+\r
+               button.addListener(SWT.Selection, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final ColorDialog dialog = new ColorDialog(button.getShell());\r
+                               final RGB result = dialog.open();\r
+                               if (result != null) {\r
+                                       SWTGraphicUtil.dispose(PWColorChooser.this.color);\r
+                                       PWColorChooser.this.color = new Color(button.getDisplay(), result);\r
+                                       drawButton(button);\r
+                                       PreferenceWindow.getInstance().setValue(getPropertyKey(), result);\r
+                               }\r
+                       }\r
+               });\r
+\r
+               button.addListener(SWT.Dispose, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               SWTGraphicUtil.dispose(PWColorChooser.this.color);\r
+                       }\r
+               });\r
+\r
+               return button;\r
+       }\r
+\r
+       /**\r
+        * @param button button on which we draw the rectangle\r
+        */\r
+       protected void drawButton(final Button button) {\r
+               final int height = (int) button.getFont().getFontData()[0].height;\r
+               final int width = button.getBounds().width - 16;\r
+\r
+               final Image newImage = new Image(button.getDisplay(), Math.max(1, width), Math.max(1, height));\r
+\r
+               final GC gc = new GC(newImage);\r
+               gc.setBackground(PWColorChooser.this.color);\r
+               gc.fillRectangle(0, 0, width, height);\r
+\r
+               gc.setForeground(button.getDisplay().getSystemColor(SWT.COLOR_BLACK));\r
+               gc.drawRectangle(0, 0, width - 1, height - 1);\r
+\r
+               gc.dispose();\r
+\r
+               button.setImage(newImage);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), null);\r
+               } else {\r
+                       if (!(value instanceof RGB)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a RGB because it is associated to a color chooser");\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWCombo.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWCombo.java
new file mode 100644 (file)
index 0000000..1960011
--- /dev/null
@@ -0,0 +1,107 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are Combo\r
+ * \r
+ */\r
+public class PWCombo extends PWWidget {\r
+\r
+       private final List<Object> data;\r
+       private final boolean editable;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWCombo(final String label, final String propertyKey, final Object... values) {\r
+               this(label, propertyKey, false, values);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWCombo(final String label, final String propertyKey, final boolean editable, final Object... values) {\r
+               super(label, propertyKey, label == null ? 1 : 2, false);\r
+               this.data = new ArrayList<Object>(Arrays.asList(values));\r
+               this.editable = editable;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               buildLabel(parent, GridData.CENTER);\r
+\r
+               final Combo combo = new Combo(parent, SWT.BORDER | (this.editable ? SWT.NONE : SWT.READ_ONLY));\r
+               addControl(combo);\r
+\r
+               for (int i = 0; i < this.data.size(); i++) {\r
+                       final Object datum = this.data.get(i);\r
+                       combo.add(datum.toString());\r
+                       if (datum.equals(PreferenceWindow.getInstance().getValueFor(getPropertyKey()))) {\r
+                               combo.select(i);\r
+                       }\r
+               }\r
+\r
+               combo.addListener(SWT.Modify, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               PreferenceWindow.getInstance().setValue(getPropertyKey(), PWCombo.this.data.get(combo.getSelectionIndex()));\r
+                       }\r
+               });\r
+\r
+               return combo;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), null);\r
+               } else {\r
+                       if (this.editable && !(value instanceof String)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a String because it is associated to an editable combo");\r
+                       }\r
+\r
+                       if (!this.data.isEmpty()) {\r
+                               if (!value.getClass().equals(this.data.get(0).getClass())) {\r
+                                       throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a " + this.data.get(0).getClass() + " because it is associated to a combo");\r
+                               }\r
+                       }\r
+\r
+               }\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWDirectoryChooser.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWDirectoryChooser.java
new file mode 100644 (file)
index 0000000..db0cd9b
--- /dev/null
@@ -0,0 +1,78 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.DirectoryDialog;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+\r
+/**\r
+ * Instances of this class are used to select a directory\r
+ */\r
+public class PWDirectoryChooser extends PWChooser {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWDirectoryChooser(final String label, final String propertyKey) {\r
+               super(label, propertyKey);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWChooser#setButtonAction(org.eclipse.swt.widgets.Text,\r
+        *      org.eclipse.swt.widgets.Button)\r
+        */\r
+       @Override\r
+       protected void setButtonAction(final Text text, final Button button) {\r
+\r
+               final String originalDirectory = (String) PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               text.setText(originalDirectory);\r
+\r
+               button.addListener(SWT.Selection, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final DirectoryDialog dialog = new DirectoryDialog(text.getShell());\r
+                               dialog.setMessage(ResourceManager.getLabel(ResourceManager.CHOOSE_DIRECTORY));\r
+                               final String result = dialog.open();\r
+                               if (result != null) {\r
+                                       text.setText(result);\r
+                                       PreferenceWindow.getInstance().setValue(getPropertyKey(), result);\r
+                               }\r
+\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), "");\r
+               } else {\r
+                       if (!(value instanceof String)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a String because it is associated to a directory chooser");\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFileChooser.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFileChooser.java
new file mode 100644 (file)
index 0000000..421aa0e
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are used to select a file\r
+ */\r
+public class PWFileChooser extends PWChooser {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWFileChooser(final String label, final String propertyKey) {\r
+               super(label, propertyKey);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWChooser#setButtonAction(org.eclipse.swt.widgets.Text,\r
+        *      org.eclipse.swt.widgets.Button)\r
+        */\r
+       @Override\r
+       protected void setButtonAction(final Text text, final Button button) {\r
+               final String originalFile = (String) PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               text.setText(originalFile);\r
+\r
+               button.addListener(SWT.Selection, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final FileDialog dialog = new FileDialog(text.getShell(), SWT.OPEN);\r
+                               final String result = dialog.open();\r
+                               if (result != null) {\r
+                                       text.setText(result);\r
+                                       PreferenceWindow.getInstance().setValue(getPropertyKey(), result);\r
+                               }\r
+\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), "");\r
+               } else {\r
+                       if (!(value instanceof String)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a String because it is associated to a file chooser");\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFloatText.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFloatText.java
new file mode 100644 (file)
index 0000000..db64468
--- /dev/null
@@ -0,0 +1,114 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.VerifyEvent;\r
+import org.eclipse.swt.events.VerifyListener;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+import org.mihalis.opal.utils.StringUtil;\r
+\r
+/**\r
+ * Instances of this class are text box to type floats\r
+ */\r
+public class PWFloatText extends PWText {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWFloatText(final String label, final String propertyKey) {\r
+               super(label, propertyKey);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#addVerifyListeners()\r
+        */\r
+       @Override\r
+       public void addVerifyListeners() {\r
+               this.text.addVerifyListener(new VerifyListener() {\r
+\r
+                       @Override\r
+                       public void verifyText(final VerifyEvent e) {\r
+                               if (e.character != 0 && !Character.isDigit(e.character) && e.keyCode != SWT.BS && e.keyCode != SWT.DEL && e.character != '.' && e.character != ',') {\r
+                                       e.doit = false;\r
+                                       return;\r
+                               }\r
+\r
+                               e.doit = verifyEntry(e.text, e.keyCode);\r
+\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Check if an entry is a float\r
+        * \r
+        * @param entry text typed by the user\r
+        * @param keyCode key code\r
+        * @return true if the user typed a float value, false otherwise\r
+        */\r
+       private boolean verifyEntry(final String entry, final int keyCode) {\r
+               final String work;\r
+               if (keyCode == SWT.DEL) {\r
+                       work = StringUtil.removeCharAt(this.text.getText(), this.text.getCaretPosition());\r
+               } else if (keyCode == SWT.BS && this.text.getCaretPosition() == 0) {\r
+                       work = StringUtil.removeCharAt(this.text.getText(), this.text.getCaretPosition() - 1);\r
+               } else if (keyCode == 0) {\r
+                       work = entry;\r
+               } else {\r
+                       work = StringUtil.insertString(this.text.getText(), entry, this.text.getCaretPosition());\r
+               }\r
+\r
+               try {\r
+                       Double.parseDouble(work.replace(',', '.'));\r
+               } catch (final NumberFormatException nfe) {\r
+                       return false;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), new Float(0));\r
+               } else {\r
+                       if (!(value instanceof Float)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a Float because it is associated to a float text widget");\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#convertValue()\r
+        */\r
+       @Override\r
+       public Object convertValue() {\r
+               return Float.parseFloat(this.text.getText());\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#getStyle()\r
+        */\r
+       @Override\r
+       public int getStyle() {\r
+               return SWT.NONE;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFontChooser.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWFontChooser.java
new file mode 100644 (file)
index 0000000..5637fe2
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.FontDialog;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+\r
+/**\r
+ * Instances of this class are used to select a font\r
+ */\r
+public class PWFontChooser extends PWChooser {\r
+       private FontData fontData;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWFontChooser(final String label, final String propertyKey) {\r
+               super(label, propertyKey);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), null);\r
+               } else {\r
+                       if (!(value instanceof FontData)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a FontData because it is associated to a font chooser");\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWChooser#setButtonAction(org.eclipse.swt.widgets.Text,\r
+        *      org.eclipse.swt.widgets.Button)\r
+        */\r
+       @Override\r
+       protected void setButtonAction(final Text text, final Button button) {\r
+               this.fontData = (FontData) PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+\r
+               button.addListener(SWT.Selection, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final FontDialog dialog = new FontDialog(text.getShell());\r
+                               final FontData result = dialog.open();\r
+                               if (result != null && result.getName() != null && !"".equals(result.getName().trim())) {\r
+                                       PWFontChooser.this.fontData = result;\r
+                                       PreferenceWindow.getInstance().setValue(getPropertyKey(), result);\r
+                                       text.setText(buildFontInformation());\r
+                               }\r
+\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * @return a string that contains data about the choosen font\r
+        */\r
+       protected String buildFontInformation() {\r
+               final StringBuilder sb = new StringBuilder();\r
+               if (this.fontData != null) {\r
+                       sb.append(this.fontData.getName()).append(",").append(this.fontData.getHeight()).append(" pt");\r
+                       if ((this.fontData.getStyle() & SWT.BOLD) == SWT.BOLD) {\r
+                               sb.append(", ").append(ResourceManager.getLabel(ResourceManager.BOLD));\r
+                       }\r
+                       if ((this.fontData.getStyle() & SWT.ITALIC) == SWT.ITALIC) {\r
+                               sb.append(", ").append(ResourceManager.getLabel(ResourceManager.ITALIC));\r
+                       }\r
+               }\r
+               return sb.toString();\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWIntegerText.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWIntegerText.java
new file mode 100644 (file)
index 0000000..8e681df
--- /dev/null
@@ -0,0 +1,84 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are text box to type Integers\r
+ */\r
+public class PWIntegerText extends PWText {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWIntegerText(final String label, final String propertyKey) {\r
+               super(label, propertyKey);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#addVerifyListeners()\r
+        */\r
+       @Override\r
+       public void addVerifyListeners() {\r
+               this.text.addListener(SWT.Verify, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event e) {\r
+                               final String string = e.text;\r
+                               final char[] chars = new char[string.length()];\r
+                               string.getChars(0, chars.length, chars, 0);\r
+                               for (int i = 0; i < chars.length; i++) {\r
+                                       if (!('0' <= chars[i] && chars[i] <= '9') && e.keyCode != SWT.BS && e.keyCode != SWT.DEL) {\r
+                                               e.doit = false;\r
+                                               return;\r
+                                       }\r
+                               }\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), new Integer(0));\r
+               } else {\r
+                       if (!(value instanceof Integer)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be an Integer because it is associated to a integer text widget");\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#convertValue()\r
+        */\r
+       @Override\r
+       public Object convertValue() {\r
+               return Integer.parseInt(this.text.getText());\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#getStyle()\r
+        */\r
+       @Override\r
+       public int getStyle() {\r
+               return SWT.NONE;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWLabel.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWLabel.java
new file mode 100644 (file)
index 0000000..bcffef7
--- /dev/null
@@ -0,0 +1,81 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are labels, that could contain some HTML tags (B,I,U)\r
+ */\r
+public class PWLabel extends PWWidget {\r
+\r
+       private StyledText labelWidget;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        */\r
+       public PWLabel(final String label) {\r
+               super(label, null, 1, true);\r
+               setAlignment(GridData.FILL);\r
+               setGrabExcessSpace(true);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               if (getLabel() == null) {\r
+                       throw new UnsupportedOperationException("You need to set a description for a PWLabel object");\r
+               }\r
+               this.labelWidget = new StyledText(parent, SWT.WRAP | SWT.READ_ONLY);\r
+               this.labelWidget.setEnabled(false);\r
+               this.labelWidget.setBackground(parent.getBackground());\r
+               this.labelWidget.setText("<html><body>" + getLabel() + "</body></html>");\r
+               SWTGraphicUtil.applyHTMLFormating(this.labelWidget);\r
+               return this.labelWidget;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#enableOrDisable()\r
+        */\r
+       @Override\r
+       public boolean enableOrDisable() {\r
+               if (this.enabler == null) {\r
+                       return true;\r
+               }\r
+\r
+               final boolean enabled = this.enabler.isEnabled();\r
+               if (!this.labelWidget.isDisposed()) {\r
+                       if (enabled) {\r
+                               this.labelWidget.setForeground(this.labelWidget.getDisplay().getSystemColor(SWT.COLOR_BLACK));\r
+                       } else {\r
+                               this.labelWidget.setForeground(this.labelWidget.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));\r
+                       }\r
+               }\r
+               return enabled;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWPasswordText.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWPasswordText.java
new file mode 100644 (file)
index 0000000..843b288
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are text box to type password\r
+ */\r
+public class PWPasswordText extends PWText {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWPasswordText(final String label, final String propertyKey) {\r
+               super(label, propertyKey);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#addVerifyListeners()\r
+        */\r
+       @Override\r
+       public void addVerifyListeners() {\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), "");\r
+               } else {\r
+                       if (!(value instanceof String)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a String because it is associated to a password text box");\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#convertValue()\r
+        */\r
+       @Override\r
+       public Object convertValue() {\r
+               return this.text.getText();\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#getStyle()\r
+        */\r
+       @Override\r
+       public int getStyle() {\r
+               return SWT.PASSWORD;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWRadio.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWRadio.java
new file mode 100644 (file)
index 0000000..3dfee00
--- /dev/null
@@ -0,0 +1,98 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are a group of radio buttons\r
+ * \r
+ */\r
+public class PWRadio extends PWWidget {\r
+\r
+       private final List<Object> data;\r
+       private final List<Button> buttons;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWRadio(final String label, final String prop, final Object... values) {\r
+               super(null, prop, label == null ? 1 : 2, false);\r
+               this.data = new ArrayList<Object>(Arrays.asList(values));\r
+               this.buttons = new ArrayList<Button>();\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               buildLabel(parent, GridData.BEGINNING);\r
+\r
+               final Composite composite = new Composite(parent, SWT.NONE);\r
+               final GridLayout gridLayout = new GridLayout();\r
+               gridLayout.marginHeight = gridLayout.marginWidth = 0;\r
+               composite.setLayout(gridLayout);\r
+\r
+               for (final Object datum : this.data) {\r
+                       final Button button = new Button(composite, SWT.RADIO);\r
+                       addControl(button);\r
+                       button.setText(datum.toString());\r
+                       button.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));\r
+                       button.setSelection(datum.equals(PreferenceWindow.getInstance().getValueFor(getPropertyKey())));\r
+                       button.setData(datum);\r
+                       button.addListener(SWT.Selection, new Listener() {\r
+                               @Override\r
+                               public void handleEvent(final Event event) {\r
+                                       if (button.getSelection()) {\r
+                                               PreferenceWindow.getInstance().setValue(getPropertyKey(), button.getData());\r
+                                       }\r
+                               }\r
+                       });\r
+\r
+                       this.buttons.add(button);\r
+               }\r
+               return composite;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), null);\r
+               } else {\r
+                       if (!this.data.isEmpty()) {\r
+                               if (!value.getClass().equals(this.data.get(0).getClass())) {\r
+                                       throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a " + this.data.get(0).getClass() + " because it is associated to a combo");\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWScale.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWScale.java
new file mode 100644 (file)
index 0000000..a6bb648
--- /dev/null
@@ -0,0 +1,91 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Scale;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are scales\r
+ */\r
+public class PWScale extends PWWidget {\r
+\r
+       private final int max;\r
+       private final int min;\r
+       private final int increment;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        * @param min minimum value\r
+        * @param max maximum value\r
+        * @param increment increment value\r
+        */\r
+       public PWScale(final String label, final String propertyKey, final int min, final int max, final int increment) {\r
+               super(label, propertyKey, label == null ? 1 : 2, false);\r
+               this.min = min;\r
+               this.max = max;\r
+               this.increment = increment;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               buildLabel(parent, GridData.CENTER);\r
+               final Scale scale = new Scale(parent, SWT.HORIZONTAL);\r
+               addControl(scale);\r
+               scale.setIncrement(this.increment);\r
+               scale.setMinimum(this.min);\r
+               scale.setMaximum(this.max);\r
+               final Integer originalValue = (Integer) PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               scale.setSelection(originalValue.intValue());\r
+\r
+               scale.addListener(SWT.Modify, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               PreferenceWindow.getInstance().setValue(getPropertyKey(), new Integer(scale.getSelection()));\r
+                       }\r
+               });\r
+\r
+               return scale;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), new Integer(this.min));\r
+               } else {\r
+                       if (!(value instanceof Integer)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be an Integer because it is associated to a iscale");\r
+                       }\r
+\r
+                       final int valueAsInt = ((Integer) value).intValue();\r
+                       if (valueAsInt < this.min || valueAsInt > this.max) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' is out of range (value is " + valueAsInt + ", range is " + this.min + "-" + this.max + ")");\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWSeparator.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWSeparator.java
new file mode 100644 (file)
index 0000000..b24032a
--- /dev/null
@@ -0,0 +1,78 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.mihalis.opal.titledSeparator.TitledSeparator;\r
+\r
+/**\r
+ * Instances of this class are separators\r
+ * \r
+ */\r
+public class PWSeparator extends PWWidget {\r
+\r
+       private final Image image;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        */\r
+       public PWSeparator() {\r
+               this(null, null);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        */\r
+       public PWSeparator(final String label) {\r
+               this(label, null);\r
+       }\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param image associated image\r
+        */\r
+       public PWSeparator(final String label, final Image image) {\r
+               super(label, null, 1, true);\r
+               this.image = image;\r
+               setAlignment(GridData.FILL);\r
+               setGrabExcessSpace(true);\r
+               setHeight(20);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               final TitledSeparator sep = new TitledSeparator(parent, SWT.NONE);\r
+               addControl(sep);\r
+               sep.setText(getLabel());\r
+               sep.setImage(this.image);\r
+               return sep;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWSpinner.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWSpinner.java
new file mode 100644 (file)
index 0000000..9fe4875
--- /dev/null
@@ -0,0 +1,86 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Spinner;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are spinners\r
+ */\r
+public class PWSpinner extends PWWidget {\r
+       private final int max;\r
+       private final int min;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        * @param min minimum value\r
+        * @param max maximum value\r
+        */\r
+       public PWSpinner(final String label, final String propertyKey, final int min, final int max) {\r
+               super(label, propertyKey, label == null ? 1 : 2, false);\r
+               this.min = min;\r
+               this.max = max;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               buildLabel(parent, GridData.CENTER);\r
+               final Spinner spinner = new Spinner(parent, SWT.HORIZONTAL | SWT.BORDER);\r
+               addControl(spinner);\r
+               spinner.setMinimum(this.min);\r
+               spinner.setMaximum(this.max);\r
+               final Integer originalValue = (Integer) PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               spinner.setSelection(originalValue.intValue());\r
+\r
+               spinner.addListener(SWT.Modify, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               PreferenceWindow.getInstance().setValue(getPropertyKey(), new Integer(spinner.getSelection()));\r
+                       }\r
+               });\r
+\r
+               return spinner;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), new Integer(this.min));\r
+               } else {\r
+                       if (!(value instanceof Integer)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be an Integer because it is associated to a spinner");\r
+                       }\r
+\r
+                       final int valueAsInt = ((Integer) value).intValue();\r
+                       if (valueAsInt < this.min || valueAsInt > this.max) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' is out of range (value is " + valueAsInt + ", range is " + this.min + "-" + this.max + ")");\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWStringText.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWStringText.java
new file mode 100644 (file)
index 0000000..bc2301a
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are text box to type Strings\r
+ */\r
+public class PWStringText extends PWText {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWStringText(final String label, final String propertyKey) {\r
+               super(label, propertyKey);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#addVerifyListeners()\r
+        */\r
+       @Override\r
+       public void addVerifyListeners() {\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), "");\r
+               } else {\r
+                       if (!(value instanceof String)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a String because it is associated to a stringtext");\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#convertValue()\r
+        */\r
+       @Override\r
+       public Object convertValue() {\r
+               return this.text.getText();\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#getStyle()\r
+        */\r
+       @Override\r
+       public int getStyle() {\r
+               return SWT.NONE;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWText.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWText.java
new file mode 100644 (file)
index 0000000..3d37a86
--- /dev/null
@@ -0,0 +1,74 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * This is the abstract class for all text widgets (except textarea)\r
+ */\r
+public abstract class PWText extends PWWidget {\r
+\r
+       protected Text text;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated property key\r
+        */\r
+       public PWText(final String label, final String propertyKey) {\r
+               super(label, propertyKey, label == null ? 1 : 2, false);\r
+               setGrabExcessSpace(true);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               buildLabel(parent, GridData.CENTER);\r
+               this.text = new Text(parent, SWT.BORDER | getStyle());\r
+               addControl(this.text);\r
+               addVerifyListeners();\r
+               this.text.setText(PreferenceWindow.getInstance().getValueFor(getPropertyKey()).toString());\r
+               this.text.addListener(SWT.Modify, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               PreferenceWindow.getInstance().setValue(getPropertyKey(), convertValue());\r
+                       }\r
+               });\r
+               return this.text;\r
+       }\r
+\r
+       /**\r
+        * Add the verify listeners\r
+        */\r
+       public abstract void addVerifyListeners();\r
+\r
+       /**\r
+        * @return the value of the data typed by the user in the correct format\r
+        */\r
+       public abstract Object convertValue();\r
+\r
+       /**\r
+        * @return the style (SWT.NONE or SWT.PASSWORD)\r
+        */\r
+       public abstract int getStyle();\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWTextarea.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWTextarea.java
new file mode 100644 (file)
index 0000000..0521707
--- /dev/null
@@ -0,0 +1,77 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+\r
+/**\r
+ * Instances of this class are text areas\r
+ * \r
+ */\r
+public class PWTextarea extends PWWidget {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWTextarea(final String label, final String propertyKey) {\r
+               super(label, propertyKey, label == null ? 1 : 2, false);\r
+               setGrabExcessSpace(true);\r
+               setHeight(50);\r
+               setWidth(350);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#build(org.eclipse.swt.widgets.Composite)\r
+        */\r
+       @Override\r
+       public Control build(final Composite parent) {\r
+               buildLabel(parent, GridData.BEGINNING);\r
+\r
+               final Text text = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);\r
+               addControl(text);\r
+               text.setText(PreferenceWindow.getInstance().getValueFor(getPropertyKey()).toString());\r
+               text.addListener(SWT.FocusOut, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               PreferenceWindow.getInstance().setValue(getPropertyKey(), text.getText());\r
+                       }\r
+               });\r
+\r
+               return text;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), "");\r
+               } else {\r
+                       if (!(value instanceof String)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a String because it is associated to a textarea");\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWURLText.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWURLText.java
new file mode 100644 (file)
index 0000000..ebb145a
--- /dev/null
@@ -0,0 +1,98 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.opalDialog.Dialog;\r
+import org.mihalis.opal.preferenceWindow.PreferenceWindow;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+\r
+/**\r
+ * Instances of this class are text box used to type URL\r
+ */\r
+public class PWURLText extends PWText {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label associated label\r
+        * @param propertyKey associated key\r
+        */\r
+       public PWURLText(final String label, final String propertyKey) {\r
+               super(label, propertyKey);\r
+               setWidth(200);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#addVerifyListeners()\r
+        */\r
+       @Override\r
+       public void addVerifyListeners() {\r
+               this.text.addListener(SWT.FocusOut, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               try {\r
+                                       new URL(PWURLText.this.text.getText());\r
+                               } catch (final MalformedURLException e) {\r
+                                       Dialog.error(ResourceManager.getLabel(ResourceManager.APPLICATION_ERROR), ResourceManager.getLabel(ResourceManager.VALID_URL));\r
+                                       event.doit = false;\r
+                                       PWURLText.this.text.forceFocus();\r
+                               }\r
+\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWWidget#check()\r
+        */\r
+       @Override\r
+       public void check() {\r
+               final Object value = PreferenceWindow.getInstance().getValueFor(getPropertyKey());\r
+               if (value == null) {\r
+                       PreferenceWindow.getInstance().setValue(getPropertyKey(), "");\r
+               } else {\r
+                       if (!(value instanceof String)) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has to be a String because it is associated to a URL text box");\r
+                       }\r
+\r
+                       try {\r
+                               new URL((String) value);\r
+                       } catch (final MalformedURLException e) {\r
+                               throw new UnsupportedOperationException("The property '" + getPropertyKey() + "' has a value (" + value + ") that is not an URL");\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#convertValue()\r
+        */\r
+       @Override\r
+       public Object convertValue() {\r
+               return this.text.getText();\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.preferenceWindow.widgets.PWText#getStyle()\r
+        */\r
+       @Override\r
+       public int getStyle() {\r
+               return SWT.NONE;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWWidget.java b/org.tizen.common.externals/src/org/mihalis/opal/preferenceWindow/widgets/PWWidget.java
new file mode 100644 (file)
index 0000000..424cf02
--- /dev/null
@@ -0,0 +1,264 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.preferenceWindow.widgets;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.mihalis.opal.preferenceWindow.enabler.Enabler;\r
+\r
+/**\r
+ * This class is the root class for all widgets that take part of a preference\r
+ * window\r
+ * \r
+ */\r
+public abstract class PWWidget {\r
+       private final String propertyKey;\r
+       private final String label;\r
+       protected Enabler enabler;\r
+       private final List<Control> controls;\r
+\r
+       private int alignment = GridData.BEGINNING;\r
+       private int indent = 0;\r
+       private int width = 100;\r
+       private int height = -1;\r
+       protected int numberOfColumns = 1;\r
+       private boolean grabExcessSpace = false;\r
+\r
+       private boolean singleWidget = false;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param label label associated to the widget\r
+        * @param propertyKey property key binded to the widget\r
+        * @param numberOfColumns number of columns taken by the widget\r
+        * @param singleWidget if true, the widget is supposed to be "alone" (used\r
+        *            for placement)\r
+        */\r
+       protected PWWidget(final String label, final String propertyKey, final int numberOfColumns, final boolean singleWidget) {\r
+               this.label = label;\r
+               this.propertyKey = propertyKey;\r
+               this.numberOfColumns = numberOfColumns;\r
+               this.singleWidget = singleWidget;\r
+               this.controls = new ArrayList<Control>();\r
+       }\r
+\r
+       /**\r
+        * Build the widget\r
+        * \r
+        * @param parent parent composite\r
+        * @return the created control\r
+        */\r
+       protected abstract Control build(Composite parent);\r
+\r
+       /**\r
+        * Build the label associated to the widget\r
+        * \r
+        * @param parent parent composite\r
+        * @param verticalAlignment vertical alignment\r
+        */\r
+       protected void buildLabel(final Composite parent, final int verticalAlignment) {\r
+               if (getLabel() != null) {\r
+                       final Label label = new Label(parent, SWT.NONE);\r
+                       label.setText(getLabel());\r
+                       final GridData labelGridData = new GridData(GridData.END, verticalAlignment, false, false);\r
+                       labelGridData.horizontalIndent = getIndent();\r
+                       label.setLayoutData(labelGridData);\r
+                       addControl(label);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Check if the property can be binded to the widget\r
+        * \r
+        * @throws UnsupportedOperationException if the property could not be binded\r
+        *             to the widget\r
+        */\r
+       protected abstract void check();\r
+\r
+       /**\r
+        * Check if the property can be binded to the widget, then build the widget\r
+        * \r
+        * @param parent parent composite\r
+        * @return the created control\r
+        */\r
+       public Control checkAndBuild(final Composite parent) {\r
+               check();\r
+               return build(parent);\r
+       }\r
+\r
+       /**\r
+        * Enable or disable the widget, depending on the associated enabler\r
+        */\r
+       public boolean enableOrDisable() {\r
+               if (this.enabler == null) {\r
+                       return true;\r
+               }\r
+\r
+               final boolean enabled = this.enabler.isEnabled();\r
+               for (final Control c : this.controls) {\r
+                       if (!c.isDisposed()) {\r
+                               c.setEnabled(enabled);\r
+                       }\r
+               }\r
+               return enabled;\r
+       }\r
+\r
+       // ------------------------------- getters & setters\r
+\r
+       /**\r
+        * @return the alignment (GridData.BEGINNING, GridData.CENTER, GridData.END,\r
+        *         GridData.FILL)\r
+        */\r
+       public int getAlignment() {\r
+               return this.alignment;\r
+       }\r
+\r
+       /**\r
+        * @return the list of controls contained in the widget\r
+        */\r
+       public List<Control> getControls() {\r
+               return this.controls;\r
+       }\r
+\r
+       /**\r
+        * @return <code>true</code> if the widget should grab the excess space\r
+        */\r
+       public boolean isGrabExcessSpace() {\r
+               return this.grabExcessSpace;\r
+       }\r
+\r
+       /**\r
+        * @return the height of the widget\r
+        */\r
+       public int getHeight() {\r
+               return this.height;\r
+       }\r
+\r
+       /**\r
+        * @return the indentation space of the widget\r
+        */\r
+       public int getIndent() {\r
+               return this.indent;\r
+       }\r
+\r
+       /**\r
+        * @return the label associated to the widget (may be <code>null</code>)\r
+        */\r
+       public String getLabel() {\r
+               return this.label;\r
+       }\r
+\r
+       /**\r
+        * @return the number of columns associated to the widget\r
+        */\r
+       public int getNumberOfColumns() {\r
+               return this.numberOfColumns;\r
+       }\r
+\r
+       /**\r
+        * @return the propertyKey associated to the widget\r
+        */\r
+       String getPropertyKey() {\r
+               return this.propertyKey;\r
+       }\r
+\r
+       /**\r
+        * @return the width of the widget\r
+        */\r
+       public int getWidth() {\r
+               return this.width;\r
+       }\r
+\r
+       /**\r
+        * @return <code>true</code> if the widget is "alone"\r
+        */\r
+       public boolean isSingleWidget() {\r
+               return this.singleWidget;\r
+       }\r
+\r
+       /**\r
+        * Adds a control to the list of control contained in the widget\r
+        * \r
+        * @param control control to add\r
+        */\r
+       protected void addControl(final Control control) {\r
+               this.controls.add(control);\r
+       }\r
+\r
+       /**\r
+        * @param alignment the alignment to set (GridData.BEGINNING,\r
+        *            GridData.CENTER, GridData.END, GridData.FILL)\r
+        * @return the widget\r
+        */\r
+       public PWWidget setAlignment(final int alignment) {\r
+               if (alignment != GridData.BEGINNING && alignment != GridData.CENTER && alignment != GridData.END && alignment != GridData.FILL) {\r
+                       throw new UnsupportedOperationException("Value should be one of the following :GridData.BEGINNING, GridData.CENTER, GridData.END, GridData.FILL");\r
+               }\r
+               this.alignment = alignment;\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @param enabler the enabler to set\r
+        * @return the widget\r
+        */\r
+       public PWWidget setEnabler(final Enabler enabler) {\r
+               this.enabler = enabler;\r
+               this.enabler.injectWidget(this);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @param grabExcessSpace true if you want the widget to grab the excess\r
+        *            space\r
+        * @return the widget\r
+        */\r
+       public PWWidget setGrabExcessSpace(final boolean grabExcessSpace) {\r
+               this.grabExcessSpace = grabExcessSpace;\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @param height the height to set\r
+        * @return the widget\r
+        */\r
+       public PWWidget setHeight(final int height) {\r
+               this.height = height;\r
+               return this;\r
+\r
+       }\r
+\r
+       /**\r
+        * @param indent the indentation space to set\r
+        * @return the widget\r
+        */\r
+       public PWWidget setIndent(final int indent) {\r
+               this.indent = indent;\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @param width the width to set\r
+        * @return the widget\r
+        */\r
+       public PWWidget setWidth(final int width) {\r
+               this.width = width;\r
+               return this;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/BaseFocusControlListener.java b/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/BaseFocusControlListener.java
new file mode 100644 (file)
index 0000000..35c65be
--- /dev/null
@@ -0,0 +1,169 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Peter Weishapl - Inspiration\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.promptSupport;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.ControlEvent;\r
+import org.eclipse.swt.events.ControlListener;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.promptSupport.PromptSupport.FocusBehavior;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Abstract class that contains code for the FocusLost, FocusGained and\r
+ * ControlResized events\r
+ * \r
+ */\r
+abstract class BaseFocusControlListener implements FocusListener, ControlListener {\r
+\r
+       protected Control control;\r
+       private boolean firstDraw;\r
+       private Font initialFont;\r
+       private Color initialBackgroundColor;\r
+       private Color initialForegroundColor;\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param control control on which this listener will be attached\r
+        */\r
+       BaseFocusControlListener(final Control control) {\r
+               this.control = control;\r
+               this.firstDraw = true;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)\r
+        */\r
+       @Override\r
+       public void focusGained(final FocusEvent e) {\r
+               if (isFilled()) {\r
+                       // Widget not empty\r
+                       return;\r
+               }\r
+\r
+               applyInitialLook();\r
+               if (PromptSupport.getFocusBehavior(this.control) == FocusBehavior.HIDE_PROMPT) {\r
+                       hidePrompt();\r
+               } else {\r
+                       highLightPrompt();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Apply the initial look of the widget\r
+        */\r
+       private void applyInitialLook() {\r
+               this.control.setFont(this.initialFont);\r
+               this.control.setBackground(this.initialBackgroundColor);\r
+               this.control.setForeground(this.initialForegroundColor);\r
+       }\r
+\r
+       /**\r
+        * Code when the focus behiaviour is "Hide"\r
+        */\r
+       protected abstract void hidePrompt();\r
+\r
+       /**\r
+        * Code when the focus behiaviour is "Highlight"\r
+        */\r
+       protected abstract void highLightPrompt();\r
+\r
+       /**\r
+        * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)\r
+        */\r
+       @Override\r
+       public void focusLost(final FocusEvent e) {\r
+               if (isFilled()) {\r
+                       return;\r
+               }\r
+\r
+               storeInitialLook();\r
+               applyForegroundColor();\r
+               applyBackgroundColor();\r
+               applyFontStyle();\r
+               fillPromptText();\r
+       }\r
+\r
+       /**\r
+        * @return <code>true</code> if the widget is filled, <code>false</code>\r
+        *         otherwise\r
+        */\r
+       protected abstract boolean isFilled();\r
+\r
+       /**\r
+        * Apply the foreground color for the prompt\r
+        */\r
+       private void applyForegroundColor() {\r
+               this.control.setForeground(PromptSupport.getForeground(this.control));\r
+       }\r
+\r
+       /**\r
+        * Apply the background color for the prompt\r
+        */\r
+       private void applyBackgroundColor() {\r
+               this.control.setBackground(PromptSupport.getBackground(this.control));\r
+       }\r
+\r
+       /**\r
+        * Apply the font style to the prompt\r
+        */\r
+       private void applyFontStyle() {\r
+               final Font font = SWTGraphicUtil.buildFontFrom(this.control, PromptSupport.getFontStyle(this.control));\r
+               this.control.setFont(font);\r
+               this.control.addListener(SWT.Dispose, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               SWTGraphicUtil.dispose(font);\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Fill the prompt text\r
+        */\r
+       protected abstract void fillPromptText();\r
+\r
+       /**\r
+        * @see org.eclipse.swt.events.ControlListener#controlMoved(org.eclipse.swt.events.ControlEvent)\r
+        */\r
+       @Override\r
+       public void controlMoved(final ControlEvent e) {\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.events.ControlListener#controlResized(org.eclipse.swt.events.ControlEvent)\r
+        */\r
+       @Override\r
+       public void controlResized(final ControlEvent e) {\r
+               if (this.firstDraw) {\r
+                       storeInitialLook();\r
+                       this.firstDraw = true;\r
+                       focusLost(null);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Store the initial look of the widget\r
+        */\r
+       private void storeInitialLook() {\r
+               this.initialFont = this.control.getFont();\r
+               this.initialBackgroundColor = this.control.getBackground();\r
+               this.initialForegroundColor = this.control.getForeground();\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/CComboFocusControlListener.java b/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/CComboFocusControlListener.java
new file mode 100644 (file)
index 0000000..5a2da07
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Peter Weishapl - Inspiration\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.promptSupport;\r
+\r
+import org.eclipse.swt.custom.CCombo;\r
+\r
+/**\r
+ * Focus/Control listener for a CCombo widget\r
+ */\r
+class CComboFocusControlListener extends BaseFocusControlListener {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param control control on which this listener will be attached\r
+        */\r
+       public CComboFocusControlListener(final CCombo control) {\r
+               super(control);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#hidePrompt()\r
+        */\r
+       @Override\r
+       protected void hidePrompt() {\r
+               ((CCombo) this.control).setText("");\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#highLightPrompt()\r
+        */\r
+       @Override\r
+       protected void highLightPrompt() {\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#fillPromptText()\r
+        */\r
+       @Override\r
+       protected void fillPromptText() {\r
+               final String promptText = PromptSupport.getPrompt(this.control);\r
+               if (promptText != null) {\r
+                       ((CCombo) this.control).setText(promptText);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#isFilled()\r
+        */\r
+       @Override\r
+       protected boolean isFilled() {\r
+               final String promptText = PromptSupport.getPrompt(this.control);\r
+               if (promptText != null && promptText.equals(((CCombo) this.control).getText().trim())) {\r
+                       return false;\r
+               }\r
+               return !"".equals(((CCombo) this.control).getText().trim());\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/ComboFocusControlListener.java b/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/ComboFocusControlListener.java
new file mode 100644 (file)
index 0000000..8e330f9
--- /dev/null
@@ -0,0 +1,73 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Peter Weishapl - Inspiration\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.promptSupport;\r
+\r
+import org.eclipse.swt.widgets.Combo;\r
+\r
+/**\r
+ * Focus/Control listener for a Combo widget\r
+ */\r
+class ComboFocusControlListener extends BaseFocusControlListener {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param control control on which this listener will be attached\r
+        */\r
+       public ComboFocusControlListener(final Combo control) {\r
+               super(control);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#hidePrompt()\r
+        */\r
+       @Override\r
+       protected void hidePrompt() {\r
+               ((Combo) this.control).setText("");\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#highLightPrompt()\r
+        */\r
+       @Override\r
+       protected void highLightPrompt() {\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#fillPromptText()\r
+        */\r
+       @Override\r
+       protected void fillPromptText() {\r
+               final String promptText = PromptSupport.getPrompt(this.control);\r
+               if (promptText != null) {\r
+                       this.control.getDisplay().asyncExec(new Runnable() {\r
+\r
+                               @Override\r
+                               public void run() {\r
+                                       ((Combo) ComboFocusControlListener.this.control).setText(promptText);\r
+                               }\r
+                       });\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#isFilled()\r
+        */\r
+       @Override\r
+       protected boolean isFilled() {\r
+               final String promptText = PromptSupport.getPrompt(this.control);\r
+               if (promptText != null && promptText.equals(((Combo) this.control).getText().trim())) {\r
+                       return false;\r
+               }\r
+               return !"".equals(((Combo) this.control).getText().trim());\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/FocusControlListenerFactory.java b/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/FocusControlListenerFactory.java
new file mode 100644 (file)
index 0000000..82671db
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Peter Weishapl - Inspiration\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.promptSupport;\r
+\r
+import org.eclipse.swt.custom.CCombo;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Text;\r
+\r
+/**\r
+ * This is a factory of focus/control listeners\r
+ * \r
+ */\r
+class FocusControlListenerFactory {\r
+\r
+       /**\r
+        * @param control control on which the listener will be added\r
+        * @return a BaseControlFocus Listener that can be attached to the events\r
+        *         focusLost, focusGained and controlResized\r
+        */\r
+       static BaseFocusControlListener getFocusControlListenerFor(final Control control) {\r
+               if (control instanceof Combo) {\r
+                       return new ComboFocusControlListener((Combo) control);\r
+               }\r
+               if (control instanceof CCombo) {\r
+                       return new CComboFocusControlListener((CCombo) control);\r
+               }\r
+\r
+               if (control instanceof Text) {\r
+                       return new TextFocusControlListener((Text) control);\r
+               }\r
+\r
+               if (control instanceof StyledText) {\r
+                       return new StyledTextFocusControlListener((StyledText) control);\r
+               }\r
+               throw new IllegalArgumentException("Control should be a Text, a Combo, a CCombo or a StyledText widget");\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/PromptSupport.java b/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/PromptSupport.java
new file mode 100644 (file)
index 0000000..d04ade6
--- /dev/null
@@ -0,0 +1,230 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Peter Weishapl - Inspiration\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.promptSupport;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CCombo;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Text;\r
+\r
+/**\r
+ * This utility class allows the user to add a prompt to a text or combo\r
+ * component (see http://designinginterfaces.com/Input_Prompt)\r
+ * \r
+ */\r
+public class PromptSupport {\r
+       public static enum FocusBehavior {\r
+               /**\r
+                * Highlight the prompt text as it would be selected.\r
+                */\r
+               HIGHLIGHT_PROMPT,\r
+               /**\r
+                * Hide the prompt text.\r
+                */\r
+               HIDE_PROMPT\r
+       };\r
+\r
+       private static final String KEY = "org.mihalis.opal.promptSupport.PromptSupport";\r
+       static final String BACKGROUND = KEY + ".background";\r
+       static final String FOREGROUND = KEY + ".foreground";\r
+       static final String STYLE = KEY + ".style";\r
+       static final String BEHAVIOR = KEY + ".behavior";\r
+       static final String PROMPT = KEY + ".prompt";\r
+       static final String SET = KEY + ".set";\r
+\r
+       /**\r
+        * <p>\r
+        * Convenience method to set the <code>promptText</code> and\r
+        * <code>promptTextColor</code> on a {@link Control}.\r
+        * </p>\r
+        * \r
+        * @param promptText Prompt Text\r
+        * @param promptForeground Foreground\r
+        * @param promptBackground Background\r
+        * @param control control\r
+        * @exception IllegalArgumentException if the control is not a Text Box, a\r
+        *                Combo Box, a StyledText or a CCombo\r
+        */\r
+       public static void init(final String promptText, final Color promptForeground, final Color promptBackground, final Control control) {\r
+               if (promptText != null && promptText.length() > 0) {\r
+                       setPrompt(promptText, control);\r
+               }\r
+               if (promptForeground != null) {\r
+                       setForeground(promptForeground, control);\r
+               }\r
+               if (promptBackground != null) {\r
+                       setBackground(promptBackground, control);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get the background color of the <code>control</code>, when no text is\r
+        * present. If no color has been set, the <code>control</code> background\r
+        * color will be returned.\r
+        * \r
+        * @param textComponent\r
+        * @return the the background color of the text component, when no text is\r
+        *         present\r
+        */\r
+       public static Color getBackground(final Control control) {\r
+               final Color temp = (Color) control.getData(BACKGROUND);\r
+               return temp == null ? control.getBackground() : temp;\r
+       }\r
+\r
+       /**\r
+        * <p>\r
+        * Sets the prompts background color on <code>control</code>. This\r
+        * background color will only be used when no text is present.\r
+        * </p>\r
+        * \r
+        * @param background\r
+        * @param control\r
+        * @exception IllegalArgumentException if the control is not a Text Box, a\r
+        *                Combo Box, a StyledText or a CCombo\r
+        */\r
+       public static void setBackground(final Color color, final Control control) {\r
+               checkControl(control);\r
+               control.setData(BACKGROUND, color);\r
+       }\r
+\r
+       /**\r
+        * Get the {@link FocusBehavior} of <code>control</code>.\r
+        * \r
+        * @param control\r
+        * @return the {@link FocusBehavior} or {@link FocusBehavior#HIDE_PROMPT} if\r
+        *         none is set\r
+        */\r
+       public static FocusBehavior getFocusBehavior(final Control control) {\r
+               final FocusBehavior temp = (FocusBehavior) control.getData(BEHAVIOR);\r
+               return temp == null ? FocusBehavior.HIDE_PROMPT : temp;\r
+\r
+       }\r
+\r
+       /**\r
+        * Sets the {@link FocusBehavior} on <code>control</code>, if it is the\r
+        * focus owner.\r
+        * \r
+        * @param focusBehavior\r
+        * @param control\r
+        * @exception IllegalArgumentException if the control is not a Text Box, a\r
+        *                Combo Box, a StyledText or a CCombo\r
+        */\r
+       public static void setFocusBehavior(final FocusBehavior focusBehavior, final Control control) {\r
+               checkControl(control);\r
+               control.setData(BEHAVIOR, focusBehavior);\r
+       }\r
+\r
+       /**\r
+        * Returns the font style of the prompt text, which is a OR mix of\r
+        * SWT.ITALIC, SWT.NONE or SWT.BOLD\r
+        * \r
+        * @param control\r
+        * @return font style of the prompt text\r
+        */\r
+       public static int getFontStyle(final Control control) {\r
+               final Integer temp = (Integer) control.getData(STYLE);\r
+               return temp == null ? SWT.ITALIC : temp;\r
+\r
+       }\r
+\r
+       /**\r
+        * <p>\r
+        * Set the style of the prompt font, which is a OR mix of SWT.ITALIC,\r
+        * SWT.NONE or SWT.BOLD\r
+        * </p>\r
+        * \r
+        * @param fontStyle\r
+        * @param control\r
+        * @exception IllegalArgumentException if the control is not a Text Box, a\r
+        *                Combo Box, a StyledText or a CCombo\r
+        */\r
+       public static void setFontStyle(final int fontStyle, final Control control) {\r
+               checkControl(control);\r
+               control.setData(STYLE, fontStyle);\r
+       }\r
+\r
+       /**\r
+        * Get the foreground color of the prompt text. If no color has been set,\r
+        * the <code>GREY</code> color will be returned.\r
+        * \r
+        * @param color\r
+        * @return the color of the prompt text or <code>GREY</code>if none is set\r
+        */\r
+       public static Color getForeground(final Control control) {\r
+               final Color temp = (Color) control.getData(FOREGROUND);\r
+               return temp == null ? control.getForeground() : temp;\r
+\r
+       }\r
+\r
+       /**\r
+        * Sets the foreground color of the prompt on <code>control</code>. This\r
+        * color will be used when no text is present.\r
+        * \r
+        * @param promptTextColor\r
+        * @param textComponent\r
+        * @exception IllegalArgumentException if the control is not a Text Box, a\r
+        *                Combo Box, a StyledText or a CCombo\r
+        */\r
+       public static void setForeground(final Color color, final Control control) {\r
+               checkControl(control);\r
+               control.setData(FOREGROUND, color);\r
+       }\r
+\r
+       /**\r
+        * Get the prompt text of <code>control</code>.\r
+        * \r
+        * @param control\r
+        * @return the prompt text\r
+        */\r
+       public static String getPrompt(final Control control) {\r
+               return (String) control.getData(PROMPT);\r
+       }\r
+\r
+       /**\r
+        * <p>\r
+        * Sets the prompt text on <code>control</code>\r
+        * </p>\r
+        * \r
+        * @param promptText\r
+        * @param textComponent\r
+        * @exception IllegalArgumentException if the control is not a Text Box, a\r
+        *                Combo Box, a StyledText or a CCombo\r
+        */\r
+       public static void setPrompt(final String promptText, final Control control) {\r
+               checkControl(control);\r
+\r
+               final boolean alreadySet = control.getData(SET) == null ? false : (Boolean) control.getData(SET);\r
+               if (alreadySet) {\r
+                       throw new IllegalArgumentException("A prompt has already been set on this control !");\r
+               }\r
+               control.setData(PROMPT, promptText);\r
+\r
+               final BaseFocusControlListener bfl = FocusControlListenerFactory.getFocusControlListenerFor(control);\r
+               control.addFocusListener(bfl);\r
+               control.addControlListener(bfl);\r
+               control.setData(SET, true);\r
+       }\r
+\r
+       /**\r
+        * Check if the control is a Text, a Combo, a StyledText or a CCombo\r
+        * \r
+        * @param control control to check\r
+        */\r
+       private static void checkControl(final Control control) {\r
+               if (!(control instanceof Text) && !(control instanceof Combo) && !(control instanceof StyledText) && !(control instanceof CCombo)) {\r
+                       throw new IllegalArgumentException("PromptSupport can only be used on a Text, a Combo, a StyledText or a CCombo widget.");\r
+               }\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/StyledTextFocusControlListener.java b/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/StyledTextFocusControlListener.java
new file mode 100644 (file)
index 0000000..2be5bca
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Peter Weishapl - Inspiration\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.promptSupport;\r
+\r
+import org.eclipse.swt.custom.StyledText;\r
+\r
+/**\r
+ * Focus/Control listener for a StyledText widget\r
+ */\r
+class StyledTextFocusControlListener extends BaseFocusControlListener {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param control control on which this listener will be attached\r
+        */\r
+       public StyledTextFocusControlListener(final StyledText control) {\r
+               super(control);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#hidePrompt()\r
+        */\r
+       @Override\r
+       protected void hidePrompt() {\r
+               ((StyledText) this.control).setText("");\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#highLightPrompt()\r
+        */\r
+       @Override\r
+       protected void highLightPrompt() {\r
+               this.control.getDisplay().asyncExec(new Runnable() {\r
+                       @Override\r
+                       public void run() {\r
+                               ((StyledText) StyledTextFocusControlListener.this.control).selectAll();\r
+\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#fillPromptText()\r
+        */\r
+       @Override\r
+       protected void fillPromptText() {\r
+               final String promptText = PromptSupport.getPrompt(this.control);\r
+               if (promptText != null) {\r
+                       ((StyledText) this.control).setText(promptText);\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#isFilled()\r
+        */\r
+       @Override\r
+       protected boolean isFilled() {\r
+               final String promptText = PromptSupport.getPrompt(this.control);\r
+               if (promptText != null && promptText.equals(((StyledText) this.control).getText().trim())) {\r
+                       return false;\r
+               }\r
+               return !"".equals(((StyledText) this.control).getText().trim());\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/TextFocusControlListener.java b/org.tizen.common.externals/src/org/mihalis/opal/promptSupport/TextFocusControlListener.java
new file mode 100644 (file)
index 0000000..f90a975
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Peter Weishapl - Inspiration\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.promptSupport;\r
+\r
+import org.eclipse.swt.widgets.Text;\r
+\r
+/**\r
+ * Focus/Control listener for a Text widget\r
+ */\r
+class TextFocusControlListener extends BaseFocusControlListener {\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param control control on which this listener will be attached\r
+        */\r
+       public TextFocusControlListener(final Text control) {\r
+               super(control);\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#hidePrompt()\r
+        */\r
+       @Override\r
+       protected void hidePrompt() {\r
+               ((Text) this.control).setText("");\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#highLightPrompt()\r
+        */\r
+       @Override\r
+       protected void highLightPrompt() {\r
+               // If we do a select all directly, it's not working !\r
+               this.control.getDisplay().asyncExec(new Runnable() {\r
+                       @Override\r
+                       public void run() {\r
+                               ((Text) TextFocusControlListener.this.control).selectAll();\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#fillPromptText()\r
+        */\r
+       @Override\r
+       protected void fillPromptText() {\r
+               final String promptText = PromptSupport.getPrompt(this.control);\r
+               if (promptText != null) {\r
+                       ((Text) this.control).setText(promptText);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.promptSupport.BaseFocusControlListener#isFilled()\r
+        */\r
+       @Override\r
+       protected boolean isFilled() {\r
+               final String promptText = PromptSupport.getPrompt(this.control);\r
+               if (promptText != null && promptText.equals(((Text) this.control).getText().trim())) {\r
+                       return false;\r
+               }\r
+               return !"".equals(((Text) this.control).getText().trim());\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/rangeSlider/RangeSlider.java b/org.tizen.common.externals/src/org/mihalis/opal/rangeSlider/RangeSlider.java
new file mode 100755 (executable)
index 0000000..620042e
--- /dev/null
@@ -0,0 +1,1060 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.rangeSlider;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class provide a separator with a title and/or an image.\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>BORDER</dd>\r
+ * <dd>HORIZONTAL</dd>\r
+ * <dd>VERTICAL</dd> *\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>Selection</dd>\r
+ * </dl>\r
+ * </p>\r
+ */\r
+public class RangeSlider extends Canvas {\r
+\r
+       private enum SELECTED_KNOB {\r
+               NONE, UPPER, LOWER\r
+       };\r
+\r
+       private int minimum;\r
+       private int maximum;\r
+       private int lowerValue;\r
+       private int upperValue;\r
+       private final List<SelectionListener> listeners;\r
+       private final Image slider, sliderHover, sliderDrag, sliderSelected;\r
+       private final Image vSlider, vSliderHover, vSliderDrag, vSliderSelected;\r
+       private int orientation;\r
+       private int increment;\r
+       private int pageIncrement;\r
+       private SELECTED_KNOB lastSelected;\r
+       private boolean dragInProgress;\r
+       private Point coordUpper;\r
+       private boolean upperHover;\r
+       private Point coordLower;\r
+       private boolean lowerHover;\r
+       private int previousUpperValue;\r
+       private int previousLowerValue;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       public RangeSlider(final Composite parent, final int style) {\r
+               super(parent, SWT.DOUBLE_BUFFERED | ((style & SWT.BORDER) == SWT.BORDER ? SWT.BORDER : SWT.NONE));\r
+               this.minimum = this.lowerValue = 0;\r
+               this.maximum = this.upperValue = 100;\r
+               this.listeners = new ArrayList<SelectionListener>();\r
+               this.increment = 1;\r
+               this.pageIncrement = 10;\r
+               this.lastSelected = SELECTED_KNOB.NONE;\r
+               this.slider = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/slider-normal.png"));\r
+               this.sliderHover = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/slider-hover.png"));\r
+               this.sliderDrag = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/slider-drag.png"));\r
+               this.sliderSelected = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/slider-selected.png"));\r
+\r
+               this.vSlider = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/h-slider-normal.png"));\r
+               this.vSliderHover = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/h-slider-hover.png"));\r
+               this.vSliderDrag = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/h-slider-drag.png"));\r
+               this.vSliderSelected = new Image(getDisplay(), this.getClass().getClassLoader().getResourceAsStream("images/h-slider-selected.png"));\r
+\r
+               if ((style & SWT.VERTICAL) == SWT.VERTICAL) {\r
+                       this.orientation = SWT.VERTICAL;\r
+               } else {\r
+                       this.orientation = SWT.HORIZONTAL;\r
+               }\r
+\r
+               addListener(SWT.Dispose, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               SWTGraphicUtil.dispose(RangeSlider.this.slider);\r
+                               SWTGraphicUtil.dispose(RangeSlider.this.sliderHover);\r
+                               SWTGraphicUtil.dispose(RangeSlider.this.sliderDrag);\r
+                               SWTGraphicUtil.dispose(RangeSlider.this.sliderSelected);\r
+\r
+                               SWTGraphicUtil.dispose(RangeSlider.this.vSlider);\r
+                               SWTGraphicUtil.dispose(RangeSlider.this.vSliderHover);\r
+                               SWTGraphicUtil.dispose(RangeSlider.this.vSliderDrag);\r
+                               SWTGraphicUtil.dispose(RangeSlider.this.vSliderSelected);\r
+                       }\r
+               });\r
+\r
+               addMouseListeners();\r
+               addListener(SWT.KeyDown, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               handleKeyDown(event);\r
+                       }\r
+               });\r
+               addPaintListener(new PaintListener() {\r
+                       @Override\r
+                       public void paintControl(final PaintEvent e) {\r
+                               drawWidget(e);\r
+\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Add the mouse listeners (mouse up, mouse down, mouse move, mouse wheel)\r
+        */\r
+       private void addMouseListeners() {\r
+               addListener(SWT.MouseDown, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event e) {\r
+                               handleMouseDown(e);\r
+                       }\r
+               });\r
+\r
+               addListener(SWT.MouseUp, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event e) {\r
+                               handleMouseUp(e);\r
+                       }\r
+               });\r
+\r
+               addListener(SWT.MouseMove, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event e) {\r
+                               handleMouseMove(e);\r
+                       }\r
+               });\r
+\r
+               addListener(SWT.MouseWheel, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event e) {\r
+                               handleMouseWheel(e);\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Code executed when the mouse is down\r
+        * \r
+        * @param e event\r
+        */\r
+       private void handleMouseDown(final Event e) {\r
+\r
+               if (this.upperHover) {\r
+                       this.dragInProgress = true;\r
+                       this.lastSelected = SELECTED_KNOB.UPPER;\r
+                       this.previousUpperValue = this.upperValue;\r
+                       return;\r
+               }\r
+\r
+               if (this.lowerHover) {\r
+                       this.dragInProgress = true;\r
+                       this.lastSelected = SELECTED_KNOB.LOWER;\r
+                       this.previousLowerValue = this.lowerValue;\r
+                       return;\r
+               }\r
+\r
+               this.dragInProgress = false;\r
+               this.lastSelected = SELECTED_KNOB.NONE;\r
+       }\r
+\r
+       /**\r
+        * Code executed when the mouse is up\r
+        * \r
+        * @param e event\r
+        */\r
+       private void handleMouseUp(final Event e) {\r
+               if (!this.dragInProgress) {\r
+                       return;\r
+               }\r
+               this.dragInProgress = false;\r
+               if (!fireSelectionListeners(e)) {\r
+                       if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               this.upperValue = this.previousUpperValue;\r
+                       } else {\r
+                               this.lowerValue = this.previousLowerValue;\r
+                       }\r
+                       redraw();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Fire all selection listeners\r
+        * \r
+        * @param event selection event\r
+        * @return <code>true</code> if no listener cancels the selection,\r
+        *         <code>false</code> otherwise\r
+        */\r
+       private boolean fireSelectionListeners(final Event event) {\r
+               for (final SelectionListener selectionListener : this.listeners) {\r
+                       final SelectionEvent selectionEvent = new SelectionEvent(event);\r
+                       selectionListener.widgetSelected(selectionEvent);\r
+                       if (!selectionEvent.doit) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Code executed when the mouse pointer is moving\r
+        * \r
+        * @param e event\r
+        */\r
+       private void handleMouseMove(final Event e) {\r
+               final int x = e.x, y = e.y;\r
+               final Image img = this.orientation == SWT.HORIZONTAL ? this.slider : this.vSlider;\r
+               this.upperHover = x >= this.coordUpper.x && x <= this.coordUpper.x + img.getBounds().width && y >= this.coordUpper.y && y <= this.coordUpper.y + img.getBounds().height;\r
+               this.lowerHover = x >= this.coordLower.x && x <= this.coordLower.x + img.getBounds().width && y >= this.coordLower.y && y <= this.coordLower.y + img.getBounds().height;\r
+\r
+               if (this.dragInProgress) {\r
+                       if (this.orientation == SWT.HORIZONTAL) {\r
+                               final int mouseValue = (int) ((x - 9f) / computePixelSizeForHorizonalSlider()) + this.minimum;\r
+                               if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                                       this.upperValue = (int) (Math.ceil(mouseValue / this.increment) * this.increment) - this.increment;\r
+                                       checkUpperValue();\r
+                               } else {\r
+                                       this.lowerValue = (int) (Math.ceil(mouseValue / this.increment) * this.increment) - this.increment;\r
+                                       checkLowerValue();\r
+                               }\r
+\r
+                       } else {\r
+                               final int mouseValue = (int) ((y - 9f) / computePixelSizeForVerticalSlider()) + this.minimum;\r
+                               if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                                       this.upperValue = (int) (Math.ceil(mouseValue / this.increment) * this.increment) - this.increment;\r
+                                       checkUpperValue();\r
+                               } else {\r
+                                       this.lowerValue = (int) (Math.ceil(mouseValue / this.increment) * this.increment) - this.increment;\r
+                                       checkLowerValue();\r
+                               }\r
+\r
+                       }\r
+               }\r
+\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * Code executed when the mouse wheel is activated\r
+        * \r
+        * @param e event\r
+        */\r
+       private void handleMouseWheel(final Event e) {\r
+               if (this.lastSelected == SELECTED_KNOB.NONE) {\r
+                       return;\r
+               }\r
+\r
+               if (this.lastSelected == SELECTED_KNOB.LOWER) {\r
+                       this.lowerValue += e.count * this.increment;\r
+                       checkLowerValue();\r
+                       redraw();\r
+               } else {\r
+                       this.upperValue += e.count * this.increment;\r
+                       checkUpperValue();\r
+                       redraw();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Check if the lower value is in ranges\r
+        */\r
+       private void checkLowerValue() {\r
+               if (this.lowerValue < this.minimum) {\r
+                       this.lowerValue = this.minimum;\r
+               }\r
+               if (this.lowerValue > this.maximum) {\r
+                       this.lowerValue = this.maximum;\r
+               }\r
+               if (this.lowerValue > this.upperValue) {\r
+                       this.lowerValue = this.upperValue;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Check if the upper value is in ranges\r
+        */\r
+       private void checkUpperValue() {\r
+               if (this.upperValue < this.minimum) {\r
+                       this.upperValue = this.minimum;\r
+               }\r
+               if (this.upperValue > this.maximum) {\r
+                       this.upperValue = this.maximum;\r
+               }\r
+               if (this.upperValue < this.lowerValue) {\r
+                       this.upperValue = this.lowerValue;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Draws the widget\r
+        * \r
+        * @param e paint event\r
+        */\r
+       private void drawWidget(final PaintEvent e) {\r
+               final Rectangle rect = this.getClientArea();\r
+               if (rect.width == 0 || rect.height == 0) {\r
+                       return;\r
+               }\r
+               e.gc.setAdvanced(true);\r
+               e.gc.setAntialias(SWT.ON);\r
+               if (this.orientation == SWT.HORIZONTAL) {\r
+                       drawHorizontalRangeSlider(e.gc);\r
+               } else {\r
+                       drawVerticalRangeSlider(e.gc);\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Draw the range slider (horizontal)\r
+        * \r
+        * @param gc graphic context\r
+        */\r
+       private void drawHorizontalRangeSlider(final GC gc) {\r
+               drawBackgroundHorizontal(gc);\r
+               drawBarsHorizontal(gc);\r
+               this.coordUpper = drawHorizontalKnob(gc, this.upperValue, true);\r
+               this.coordLower = drawHorizontalKnob(gc, this.lowerValue, false);\r
+       }\r
+\r
+       /**\r
+        * Draw the background\r
+        * \r
+        * @param gc graphic context\r
+        */\r
+       private void drawBackgroundHorizontal(final GC gc) {\r
+               final Rectangle clientArea = this.getClientArea();\r
+\r
+               gc.setBackground(getBackground());\r
+               gc.fillRectangle(clientArea);\r
+\r
+               if (isEnabled()) {\r
+                       gc.setForeground(getForeground());\r
+               } else {\r
+                       gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_GRAY));\r
+               }\r
+               gc.drawRoundRectangle(9, 9, clientArea.width - 20, clientArea.height - 20, 3, 3);\r
+\r
+               final float pixelSize = computePixelSizeForHorizonalSlider();\r
+               final int startX = (int) (pixelSize * this.lowerValue);\r
+               final int endX = (int) (pixelSize * this.upperValue);\r
+               if (isEnabled()) {\r
+                       gc.setBackground(getForeground());\r
+               } else {\r
+                       gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_GRAY));\r
+               }\r
+               gc.fillRectangle(12 + startX, 9, endX - startX - 6, clientArea.height - 20);\r
+\r
+       }\r
+\r
+       /**\r
+        * @return how many pixels corresponds to 1 point of value\r
+        */\r
+       private float computePixelSizeForHorizonalSlider() {\r
+               return (getClientArea().width - 20f) / (this.maximum - this.minimum);\r
+       }\r
+\r
+       /**\r
+        * Draw the bars\r
+        * \r
+        * @param gc graphic context\r
+        */\r
+       private void drawBarsHorizontal(final GC gc) {\r
+               final Rectangle clientArea = this.getClientArea();\r
+               if (isEnabled()) {\r
+                       gc.setForeground(getForeground());\r
+               } else {\r
+                       gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_GRAY));\r
+               }\r
+\r
+               final float pixelSize = computePixelSizeForHorizonalSlider();\r
+               for (int i = 1; i < 10; i++) {\r
+                       final int x = (int) (9 + pixelSize * (this.maximum - this.minimum) / 10 * i);\r
+                       gc.drawLine(x, 4, x, 7);\r
+                       gc.drawLine(x, clientArea.height - 6, x, clientArea.height - 9);\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Draws an horizontal knob\r
+        * \r
+        * @param gc graphic context\r
+        * @param value corresponding value\r
+        * @param upper if <code>true</code>, draws the upper knob. If\r
+        *            <code>false</code>, draws the lower knob\r
+        * @return the coordinate of the upper left corner of the knob\r
+        */\r
+       private Point drawHorizontalKnob(final GC gc, final int value, final boolean upper) {\r
+               final float pixelSize = computePixelSizeForHorizonalSlider();\r
+               final int x = (int) (pixelSize * value);\r
+               Image image;\r
+               if (upper) {\r
+                       if (this.upperHover) {\r
+                               image = this.dragInProgress ? this.sliderDrag : this.sliderHover;\r
+                       } else if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               image = this.sliderSelected;\r
+                       } else {\r
+                               image = this.slider;\r
+                       }\r
+               } else {\r
+                       if (this.lowerHover) {\r
+                               image = this.dragInProgress ? this.sliderDrag : this.sliderHover;\r
+                       } else if (this.lastSelected == SELECTED_KNOB.LOWER) {\r
+                               image = this.sliderSelected;\r
+                       } else {\r
+                               image = this.slider;\r
+                       }\r
+               }\r
+               if (isEnabled()) {\r
+                       gc.drawImage(image, x + 5, getClientArea().height / 2 - this.slider.getBounds().height / 2);\r
+               } else {\r
+                       final Image temp = new Image(getDisplay(), image, SWT.IMAGE_DISABLE);\r
+                       gc.drawImage(temp, x + 5, getClientArea().height / 2 - this.slider.getBounds().height / 2);\r
+                       temp.dispose();\r
+               }\r
+               return new Point(x + 5, getClientArea().height / 2 - this.slider.getBounds().height / 2);\r
+       }\r
+\r
+       /**\r
+        * Draw the range slider (vertical)\r
+        * \r
+        * @param gc graphic context\r
+        */\r
+       private void drawVerticalRangeSlider(final GC gc) {\r
+               drawBackgroundVertical(gc);\r
+               drawBarsVertical(gc);\r
+               this.coordUpper = drawVerticalKnob(gc, this.upperValue, true);\r
+               this.coordLower = drawVerticalKnob(gc, this.lowerValue, false);\r
+       }\r
+\r
+       /**\r
+        * Draws the background\r
+        * \r
+        * @param gc graphic context\r
+        */\r
+       private void drawBackgroundVertical(final GC gc) {\r
+               final Rectangle clientArea = this.getClientArea();\r
+               gc.setBackground(getBackground());\r
+               gc.fillRectangle(clientArea);\r
+\r
+               if (isEnabled()) {\r
+                       gc.setForeground(getForeground());\r
+               } else {\r
+                       gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_GRAY));\r
+               }\r
+               gc.drawRoundRectangle(9, 9, clientArea.width - 20, clientArea.height - 20, 3, 3);\r
+\r
+               final float pixelSize = computePixelSizeForVerticalSlider();\r
+               final int startY = (int) (pixelSize * this.lowerValue);\r
+               final int endY = (int) (pixelSize * this.upperValue);\r
+               if (isEnabled()) {\r
+                       gc.setBackground(getForeground());\r
+               } else {\r
+                       gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_GRAY));\r
+               }\r
+               gc.fillRectangle(9, 12 + startY, clientArea.width - 20, endY - startY - 6);\r
+\r
+       }\r
+\r
+       /**\r
+        * @return how many pixels corresponds to 1 point of value\r
+        */\r
+       private float computePixelSizeForVerticalSlider() {\r
+               return (getClientArea().height - 20f) / (this.maximum - this.minimum);\r
+       }\r
+\r
+       /**\r
+        * Draws the bars\r
+        * \r
+        * @param gc graphic context\r
+        */\r
+       private void drawBarsVertical(final GC gc) {\r
+               final Rectangle clientArea = this.getClientArea();\r
+               if (isEnabled()) {\r
+                       gc.setForeground(getForeground());\r
+               } else {\r
+                       gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_GRAY));\r
+               }\r
+\r
+               final float pixelSize = computePixelSizeForVerticalSlider();\r
+               for (int i = 1; i < 10; i++) {\r
+                       final int y = (int) (9 + pixelSize * (this.maximum - this.minimum) / 10 * i);\r
+                       gc.drawLine(4, y, 7, y);\r
+                       gc.drawLine(clientArea.width - 6, y, clientArea.width - 9, y);\r
+\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Draws a vertical knob\r
+        * \r
+        * @param gc graphic context\r
+        * @param value corresponding value\r
+        * @param upper if <code>true</code>, draws the upper knob. If\r
+        *            <code>false</code>, draws the lower knob\r
+        * @return the coordinate of the upper left corner of the knob\r
+        */\r
+       private Point drawVerticalKnob(final GC gc, final int value, final boolean upper) {\r
+               final float pixelSize = computePixelSizeForVerticalSlider();\r
+               final int y = (int) (pixelSize * value);\r
+\r
+               Image image;\r
+               if (upper) {\r
+                       if (this.upperHover) {\r
+                               image = this.dragInProgress ? this.vSliderDrag : this.vSliderHover;\r
+                       } else if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               image = this.vSliderSelected;\r
+                       } else {\r
+                               image = this.vSlider;\r
+                       }\r
+               } else {\r
+                       if (this.lowerHover) {\r
+                               image = this.dragInProgress ? this.vSliderDrag : this.vSliderHover;\r
+                       } else if (this.lastSelected == SELECTED_KNOB.LOWER) {\r
+                               image = this.vSliderSelected;\r
+                       } else {\r
+                               image = this.vSlider;\r
+                       }\r
+               }\r
+\r
+               if (isEnabled()) {\r
+                       gc.drawImage(image, getClientArea().width / 2 - 8, y + 2);\r
+               } else {\r
+                       final Image temp = new Image(getDisplay(), image, SWT.IMAGE_DISABLE);\r
+                       gc.drawImage(temp, getClientArea().width / 2 - 8, y + 2);\r
+                       temp.dispose();\r
+\r
+               }\r
+               return new Point(getClientArea().width / 2 - 8, y + 2);\r
+       }\r
+\r
+       /**\r
+        * Code executed when a key is typed\r
+        * \r
+        * @param event event\r
+        */\r
+       private void handleKeyDown(final Event event) {\r
+\r
+               boolean needRedraw = false;\r
+\r
+               if (this.lastSelected == SELECTED_KNOB.NONE) {\r
+                       this.lastSelected = SELECTED_KNOB.LOWER;\r
+               }\r
+\r
+               switch (event.keyCode) {\r
+               case SWT.HOME:\r
+                       if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               this.upperValue = this.minimum;\r
+                       } else {\r
+                               this.lowerValue = this.minimum;\r
+                       }\r
+                       needRedraw = true;\r
+                       break;\r
+               case SWT.END:\r
+                       if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               this.upperValue = this.maximum;\r
+                       } else {\r
+                               this.upperValue = this.maximum;\r
+                       }\r
+                       needRedraw = true;\r
+                       break;\r
+               case SWT.PAGE_UP:\r
+                       if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               this.upperValue += this.pageIncrement;\r
+                       } else {\r
+                               this.lowerValue += this.pageIncrement;\r
+                       }\r
+                       needRedraw = true;\r
+                       break;\r
+               case SWT.PAGE_DOWN:\r
+                       if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               this.upperValue -= this.pageIncrement;\r
+                       } else {\r
+                               this.lowerValue -= this.pageIncrement;\r
+                       }\r
+                       needRedraw = true;\r
+                       break;\r
+               case SWT.ARROW_LEFT:\r
+               case SWT.ARROW_UP:\r
+                       if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               this.upperValue -= this.increment;\r
+                       } else {\r
+                               this.lowerValue -= this.increment;\r
+                       }\r
+                       needRedraw = true;\r
+                       break;\r
+               case SWT.ARROW_RIGHT:\r
+               case SWT.ARROW_DOWN:\r
+                       if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               this.upperValue += this.increment;\r
+                       } else {\r
+                               this.lowerValue += this.increment;\r
+                       }\r
+                       needRedraw = true;\r
+                       break;\r
+        default:\r
+            break;\r
+               }\r
+\r
+               if (needRedraw) {\r
+                       if (this.lastSelected == SELECTED_KNOB.UPPER) {\r
+                               checkUpperValue();\r
+                       } else {\r
+                               checkLowerValue();\r
+                       }\r
+                       redraw();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Adds the listener to the collection of listeners who will be notified\r
+        * when the user changes the receiver's value, by sending it one of the\r
+        * messages defined in the <code>SelectionListener</code> interface.\r
+        * <p>\r
+        * <code>widgetSelected</code> is called when the user changes the\r
+        * receiver's value. <code>widgetDefaultSelected</code> is not called.\r
+        * </p>\r
+        * \r
+        * @param listener the listener which should be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #removeSelectionListener\r
+        */\r
+       public void addSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               this.listeners.add(listener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)\r
+        */\r
+       @Override\r
+       public Point computeSize(final int wHint, final int hHint, final boolean changed) {\r
+               final int width, height;\r
+               checkWidget();\r
+               if (this.orientation == SWT.HORIZONTAL) {\r
+                       if (wHint < 100) {\r
+                               width = 100;\r
+                       } else {\r
+                               width = wHint;\r
+                       }\r
+\r
+                       if (hHint < 30) {\r
+                               height = 30;\r
+                       } else {\r
+                               height = hHint;\r
+                       }\r
+               } else {\r
+                       if (wHint < 30) {\r
+                               width = 30;\r
+                       } else {\r
+                               width = wHint;\r
+                       }\r
+\r
+                       if (hHint < 100) {\r
+                               height = 100;\r
+                       } else {\r
+                               height = hHint;\r
+                       }\r
+               }\r
+\r
+               return new Point(width, height);\r
+       }\r
+\r
+       /**\r
+        * Returns the amount that the selected receiver's value will be modified by\r
+        * when the up/down (or right/left) arrows are pressed.\r
+        * \r
+        * @return the increment\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getIncrement() {\r
+               checkWidget();\r
+               return this.increment;\r
+       }\r
+\r
+       /**\r
+        * Returns the 'lower selection', which is the lower receiver's position.\r
+        * \r
+        * @return the selection\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getLowerValue() {\r
+               checkWidget();\r
+               return this.lowerValue;\r
+       }\r
+\r
+       /**\r
+        * Returns the maximum value which the receiver will allow.\r
+        * \r
+        * @return the maximum\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getMaximum() {\r
+               checkWidget();\r
+               return this.maximum;\r
+       }\r
+\r
+       /**\r
+        * Returns the minimum value which the receiver will allow.\r
+        * \r
+        * @return the minimum\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getMinimum() {\r
+               checkWidget();\r
+               return this.minimum;\r
+       }\r
+\r
+       /**\r
+        * Returns the amount that the selected receiver's value will be modified by\r
+        * when the page increment/decrement areas are selected.\r
+        * \r
+        * @return the page increment\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getPageIncrement() {\r
+               checkWidget();\r
+               return this.pageIncrement;\r
+       }\r
+\r
+       /**\r
+        * Returns the 'selection', which is an array where the first element is the\r
+        * lower selection, and the second element is the upper selection\r
+        * \r
+        * @return the selection\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int[] getSelection() {\r
+               checkWidget();\r
+               final int[] selection = new int[2];\r
+               selection[0] = this.lowerValue;\r
+               selection[1] = this.upperValue;\r
+               return selection;\r
+       }\r
+\r
+       /**\r
+        * Returns the 'upper selection', which is the upper receiver's position.\r
+        * \r
+        * @return the selection\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getUpperValue() {\r
+               checkWidget();\r
+               return this.upperValue;\r
+       }\r
+\r
+       /**\r
+        * Removes the listener from the collection of listeners who will be\r
+        * notified when the user changes the receiver's value.\r
+        * \r
+        * @param listener the listener which should no longer be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #addSelectionListener\r
+        */\r
+       public void removeSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               this.listeners.remove(listener);\r
+       }\r
+\r
+       /**\r
+        * Sets the amount that the selected receiver's value will be modified by\r
+        * when the up/down (or right/left) arrows are pressed to the argument,\r
+        * which must be at least one.\r
+        * \r
+        * @param increment the new increment (must be greater than zero)\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setIncrement(final int increment) {\r
+               checkWidget();\r
+               this.increment = increment;\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * Sets the 'lower selection', which is the receiver's lower value, to the\r
+        * argument which must be greater than or equal to zero.\r
+        * \r
+        * @param value the new selection (must be zero or greater)\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setLowerValue(final int value) {\r
+               checkWidget();\r
+               if (this.minimum <= value && value <= this.maximum && value <= this.upperValue) {\r
+                       this.lowerValue = value;\r
+               }\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * Sets the maximum value that the receiver will allow. This new value will\r
+        * be ignored if it is not greater than the receiver's current minimum\r
+        * value. If the new maximum is applied then the receiver's selection value\r
+        * will be adjusted if necessary to fall within its new range.\r
+        * \r
+        * @param value the new maximum, which must be greater than the current\r
+        *            minimum\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setMaximum(final int value) {\r
+               checkWidget();\r
+               if (this.minimum <= value) {\r
+                       this.maximum = value;\r
+                       if (this.lowerValue >= this.maximum) {\r
+                               this.lowerValue = this.maximum;\r
+                       }\r
+                       if (this.upperValue >= this.maximum) {\r
+                               this.upperValue = this.maximum;\r
+                       }\r
+               }\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * Sets the minimum value that the receiver will allow. This new value will\r
+        * be ignored if it is negative or is not less than the receiver's current\r
+        * maximum value. If the new minimum is applied then the receiver's\r
+        * selection value will be adjusted if necessary to fall within its new\r
+        * range.\r
+        * \r
+        * @param value the new minimum, which must be nonnegative and less than the\r
+        *            current maximum\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setMinimum(final int value) {\r
+               checkWidget();\r
+               if (this.maximum >= value) {\r
+                       this.minimum = value;\r
+                       if (this.lowerValue <= this.minimum) {\r
+                               this.lowerValue = this.minimum;\r
+                       }\r
+                       if (this.upperValue <= this.minimum) {\r
+                               this.upperValue = this.minimum;\r
+                       }\r
+               }\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * Sets the amount that the receiver's value will be modified by when the\r
+        * page increment/decrement areas are selected to the argument, which must\r
+        * be at least one.\r
+        * \r
+        * @param pageIncrement the page increment (must be greater than zero)\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setPageIncrement(final int pageIncrement) {\r
+               checkWidget();\r
+               this.pageIncrement = pageIncrement;\r
+       }\r
+\r
+       /**\r
+        * Sets the 'selection', which is the receiver's value, to the argument\r
+        * which must be greater than or equal to zero.\r
+        * \r
+        * @param value the new selection (first value is lower value, second value\r
+        *            is upper value)\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setSelection(final int[] values) {\r
+               checkWidget();\r
+               setLowerValue(values[0]);\r
+               setUpperValue(values[1]);\r
+               checkUpperValue();\r
+               checkLowerValue();\r
+               redraw();\r
+       }\r
+\r
+       /**\r
+        * Sets the 'selection', which is the receiver's value, argument which must\r
+        * be greater than or equal to zero.\r
+        * \r
+        * @param lowerValue the new lower selection (must be zero or greater)\r
+        * @param upperValue the new upper selection (must be zero or greater)\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setSelection(final int lowerValue, final int upperValue) {\r
+               checkWidget();\r
+               setLowerValue(lowerValue);\r
+               setUpperValue(upperValue);\r
+       }\r
+\r
+       /**\r
+        * Sets the 'upper selection', which is the upper receiver's value, argument\r
+        * which must be greater than or equal to zero.\r
+        * \r
+        * @param value the new selection (must be zero or greater)\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setUpperValue(final int value) {\r
+               checkWidget();\r
+               if (this.minimum <= value && value <= this.maximum && value >= this.lowerValue) {\r
+                       this.upperValue = value;\r
+               }\r
+               redraw();\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/switchButton/SwitchButton.java b/org.tizen.common.externals/src/org/mihalis/opal/switchButton/SwitchButton.java
new file mode 100644 (file)
index 0000000..c3b0c3c
--- /dev/null
@@ -0,0 +1,938 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.switchButton;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.events.MouseAdapter;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.events.MouseTrackListener;\r
+import org.eclipse.swt.events.PaintEvent;\r
+import org.eclipse.swt.events.PaintListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Canvas;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+\r
+/**\r
+ * Instances of this class are simple switch button.\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>Selection</dd>\r
+ * </dl>\r
+ */\r
+public class SwitchButton extends Canvas {\r
+\r
+       /**\r
+        * Selection\r
+        */\r
+       private boolean selection;\r
+\r
+       /**\r
+        * Text displayed for the selected value (default = "On")\r
+        */\r
+       private String textForSelect;\r
+\r
+       /**\r
+        * Text displayed for the unselected value (default = "Off")\r
+        */\r
+       private String textForUnselect;\r
+\r
+       /**\r
+        * Text corresponding to the button (default is "")\r
+        */\r
+       private String text;\r
+\r
+       /**\r
+        * If true, display round rectangles instead of rectangles (default value is\r
+        * true)\r
+        */\r
+       private boolean round;\r
+\r
+       /**\r
+        * if not null, displays a rectangle (or a round rectangle) around the whole\r
+        * widget. Default value is null.\r
+        */\r
+       private Color borderColor;\r
+\r
+       /**\r
+        * if not null, displays a glow effect when the mouse is over the widget.\r
+        * Default value is null.\r
+        */\r
+       private Color focusColor;\r
+\r
+       /**\r
+        * Colors when the button is selected\r
+        */\r
+       private Color selectedForegroundColor, selectedBackgroundColor;\r
+\r
+       /**\r
+        * Colors when the button is not selected\r
+        */\r
+       private Color unselectedForegroundColor, unselectedBackgroundColor;\r
+\r
+       /**\r
+        * Colors for the button\r
+        */\r
+       private Color buttonBorderColor, buttonBackgroundColor1, buttonBackgroundColor2;\r
+\r
+       /**\r
+        * Gap between the button and the text (default value is 5)\r
+        */\r
+       private int gap;\r
+\r
+       /**\r
+        * Margin inside the button\r
+        */\r
+       private static final int INSIDE_BUTTON_MARGIN = 5;\r
+\r
+       /**\r
+        * Graphical context for this button\r
+        */\r
+       private GC gc;\r
+\r
+       /**\r
+        * List of selection listeners\r
+        */\r
+       private final List<SelectionListener> listOfSelectionListeners;\r
+\r
+       /**\r
+        * True when the mouse entered the widget\r
+        */\r
+       private boolean mouseInside;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       public SwitchButton(final Composite parent, final int style) {\r
+               super(parent, style | SWT.DOUBLE_BUFFERED);\r
+\r
+               this.selection = false;\r
+               this.textForSelect = "On";\r
+               this.textForUnselect = "Off";\r
+               this.round = true;\r
+               this.borderColor = null;\r
+               this.focusColor = this.getDisplay().getSystemColor(SWT.COLOR_YELLOW);\r
+               this.selectedForegroundColor = this.getDisplay().getSystemColor(SWT.COLOR_WHITE);\r
+               this.selectedBackgroundColor = new Color(this.getDisplay(), 0, 112, 195);\r
+               this.unselectedForegroundColor = this.getDisplay().getSystemColor(SWT.COLOR_BLACK);\r
+               this.unselectedBackgroundColor = new Color(this.getDisplay(), 203, 203, 203);\r
+\r
+               this.buttonBorderColor = new Color(this.getDisplay(), 96, 96, 96);\r
+               this.buttonBackgroundColor1 = new Color(this.getDisplay(), 254, 254, 254);\r
+               this.buttonBackgroundColor2 = new Color(this.getDisplay(), 192, 192, 192);\r
+\r
+               this.gap = 5;\r
+\r
+               this.listOfSelectionListeners = new ArrayList<SelectionListener>();\r
+\r
+               this.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               SwitchButton.this.selectedBackgroundColor.dispose();\r
+                               SwitchButton.this.unselectedBackgroundColor.dispose();\r
+                               SwitchButton.this.buttonBorderColor.dispose();\r
+                               SwitchButton.this.buttonBackgroundColor1.dispose();\r
+                               SwitchButton.this.buttonBackgroundColor2.dispose();\r
+                       }\r
+               });\r
+\r
+               this.addPaintListener(new PaintListener() {\r
+                       @Override\r
+                       public void paintControl(final PaintEvent event) {\r
+                               SwitchButton.this.onPaint(event);\r
+                       }\r
+               });\r
+\r
+               this.addMouseListener(new MouseAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent)\r
+                        */\r
+                       @Override\r
+                       public void mouseUp(final MouseEvent e) {\r
+                               if (SwitchButton.this.fireSelectionListeners(e)) {\r
+                                       SwitchButton.this.selection = !SwitchButton.this.selection;\r
+                                       SwitchButton.this.redraw();\r
+                               }\r
+                       }\r
+\r
+               });\r
+\r
+               this.mouseInside = false;\r
+               this.addMouseTrackListener(new MouseTrackListener() {\r
+\r
+                       @Override\r
+                       public void mouseHover(final MouseEvent e) {\r
+                               SwitchButton.this.mouseInside = true;\r
+                               SwitchButton.this.redraw();\r
+                       }\r
+\r
+                       @Override\r
+                       public void mouseExit(final MouseEvent e) {\r
+                               SwitchButton.this.mouseInside = false;\r
+                               SwitchButton.this.redraw();\r
+                       }\r
+\r
+                       @Override\r
+                       public void mouseEnter(final MouseEvent e) {\r
+                               SwitchButton.this.mouseInside = true;\r
+                               SwitchButton.this.redraw();\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Paint the widget\r
+        * \r
+        * @param event paint event\r
+        */\r
+       private void onPaint(final PaintEvent event) {\r
+               final Rectangle rect = this.getClientArea();\r
+               if (rect.width == 0 || rect.height == 0) {\r
+                       return;\r
+               }\r
+               this.gc = event.gc;\r
+               this.gc.setAntialias(SWT.ON);\r
+\r
+               final Point buttonSize = this.computeButtonSize();\r
+               this.drawSwitchButton(buttonSize);\r
+               this.drawText(buttonSize);\r
+\r
+               if (this.borderColor != null) {\r
+                       this.drawBorder();\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Draw the switch button\r
+        * \r
+        * @param buttonSize size of the button\r
+        */\r
+       private void drawSwitchButton(final Point buttonSize) {\r
+               // Draw the background of the button\r
+               this.gc.setForeground(this.buttonBorderColor);\r
+               if (this.round) {\r
+                       this.gc.drawRoundRectangle(2, 2, buttonSize.x, buttonSize.y, 3, 3);\r
+               } else {\r
+                       this.gc.drawRectangle(2, 2, buttonSize.x, buttonSize.y);\r
+               }\r
+\r
+               this.drawRightPart(buttonSize);\r
+               this.drawLeftPart(buttonSize);\r
+               this.gc.setClipping(this.getClientArea());\r
+               this.drawToggleButton(buttonSize);\r
+       }\r
+\r
+       /**\r
+        * Draw the right part of the button\r
+        * \r
+        * @param buttonSize size of the button\r
+        */\r
+       private void drawRightPart(final Point buttonSize) {\r
+               this.gc.setForeground(this.selectedBackgroundColor);\r
+               this.gc.setBackground(this.selectedBackgroundColor);\r
+               this.gc.setClipping(3, 3, buttonSize.x / 2, buttonSize.y - 1);\r
+               if (this.round) {\r
+                       this.gc.fillRoundRectangle(2, 2, buttonSize.x, buttonSize.y, 3, 3);\r
+               } else {\r
+                       this.gc.fillRectangle(2, 2, buttonSize.x, buttonSize.y);\r
+               }\r
+               this.gc.setForeground(this.selectedForegroundColor);\r
+               final Point textSize = this.gc.textExtent(this.textForSelect);\r
+               this.gc.drawString(this.textForSelect, (buttonSize.x / 2 - textSize.x) / 2 + 3, (buttonSize.y - textSize.y) / 2 + 3);\r
+       }\r
+\r
+       /**\r
+        * Draw the left part of the button\r
+        * \r
+        * @param buttonSize size of the button\r
+        */\r
+       private void drawLeftPart(final Point buttonSize) {\r
+               this.gc.setForeground(this.unselectedBackgroundColor);\r
+               this.gc.setBackground(this.unselectedBackgroundColor);\r
+               this.gc.setClipping(buttonSize.x / 2 + 3, 3, buttonSize.x / 2, buttonSize.y - 1);\r
+               if (this.round) {\r
+                       this.gc.fillRoundRectangle(2, 2, buttonSize.x, buttonSize.y, 3, 3);\r
+               } else {\r
+                       this.gc.fillRectangle(2, 2, buttonSize.x, buttonSize.y);\r
+               }\r
+               this.gc.setForeground(this.unselectedForegroundColor);\r
+               final Point textSize = this.gc.textExtent(this.textForUnselect);\r
+\r
+               this.gc.drawString(this.textForUnselect, buttonSize.x / 2 + (buttonSize.x / 2 - textSize.x) / 2 + 3, (buttonSize.y - textSize.y) / 2 + 3);\r
+       }\r
+\r
+       /**\r
+        * Draw the toggle button\r
+        * \r
+        * @param buttonSize size of the button\r
+        */\r
+       private void drawToggleButton(final Point buttonSize) {\r
+               this.gc.setForeground(this.buttonBackgroundColor1);\r
+               this.gc.setBackground(this.buttonBackgroundColor2);\r
+               if (this.selection) {\r
+                       this.gc.fillGradientRectangle(3, 3, buttonSize.x / 2, buttonSize.y, true);\r
+               } else {\r
+                       this.gc.fillGradientRectangle(buttonSize.x / 2, 3, buttonSize.x / 2 + 2, buttonSize.y - 1, true);\r
+               }\r
+\r
+               this.gc.setForeground(this.buttonBorderColor);\r
+               if (this.selection) {\r
+                       this.gc.drawRoundRectangle(2, 2, buttonSize.x / 2, buttonSize.y, 3, 3);\r
+               } else {\r
+                       this.gc.drawRoundRectangle(buttonSize.x / 2, 2, buttonSize.x / 2 + 2, buttonSize.y, 3, 3);\r
+               }\r
+\r
+               if (this.focusColor != null && this.mouseInside) {\r
+                       this.gc.setForeground(this.focusColor);\r
+                       this.gc.setLineWidth(2);\r
+                       if (this.selection) {\r
+                               this.gc.drawRoundRectangle(3, 3, buttonSize.x / 2, buttonSize.y - 1, 3, 3);\r
+                       } else {\r
+                               this.gc.drawRoundRectangle(buttonSize.x / 2 + 1, 3, buttonSize.x / 2, buttonSize.y - 2, 3, 3);\r
+                       }\r
+                       this.gc.setLineWidth(1);\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * @return the button size\r
+        */\r
+       private Point computeButtonSize() {\r
+               // Compute size for the left part\r
+               final Point sizeForLeftPart = this.gc.stringExtent(this.textForSelect);\r
+               // Compute size for the right part\r
+               final Point sizeForRightPart = this.gc.stringExtent(this.textForUnselect);\r
+\r
+               // Compute whole size\r
+               final int width = Math.max(sizeForLeftPart.x, sizeForRightPart.x) * 2 + 2 * INSIDE_BUTTON_MARGIN;\r
+               final int height = Math.max(sizeForLeftPart.y, sizeForRightPart.y) + 2 * INSIDE_BUTTON_MARGIN;\r
+\r
+               return new Point(width, height);\r
+       }\r
+\r
+       /**\r
+        * Draws the text besides the button\r
+        * \r
+        * @param buttonSize whole size of the button\r
+        */\r
+       private void drawText(final Point buttonSize) {\r
+               this.gc.setForeground(this.getForeground());\r
+               this.gc.setBackground(this.getBackground());\r
+\r
+               final int widgetHeight = this.computeSize(0, 0, true).y;\r
+               final int textHeight = this.gc.stringExtent(this.text).y;\r
+               final int x = 2 + buttonSize.x + this.gap;\r
+\r
+               this.gc.drawString(this.text, x, (widgetHeight - textHeight) / 2);\r
+       }\r
+\r
+       /**\r
+        * Draw (eventually) the border around the button\r
+        */\r
+       private void drawBorder() {\r
+               if (this.borderColor == null) {\r
+                       return;\r
+               }\r
+\r
+               this.gc.setForeground(this.borderColor);\r
+               final Point temp = this.computeSize(0, 0, false);\r
+               if (this.round) {\r
+                       this.gc.drawRoundRectangle(0, 0, temp.x - 2, temp.y - 2, 3, 3);\r
+               } else {\r
+                       this.gc.drawRectangle(0, 0, temp.x - 2, temp.y - 2);\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Fire the selection listeners\r
+        * \r
+        * @param mouseEvent mouse event\r
+        * @return true if the selection could be changed, false otherwise\r
+        */\r
+       private boolean fireSelectionListeners(final MouseEvent mouseEvent) {\r
+               for (final SelectionListener listener : this.listOfSelectionListeners) {\r
+                       final Event event = new Event();\r
+\r
+                       event.button = mouseEvent.button;\r
+                       event.display = this.getDisplay();\r
+                       event.item = null;\r
+                       event.widget = this;\r
+                       event.data = null;\r
+                       event.time = mouseEvent.time;\r
+                       event.x = mouseEvent.x;\r
+                       event.y = mouseEvent.y;\r
+\r
+                       final SelectionEvent selEvent = new SelectionEvent(event);\r
+                       listener.widgetSelected(selEvent);\r
+                       if (!selEvent.doit) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Adds the listener to the collection of listeners who will be notified\r
+        * when the control is selected by the user, by sending it one of the\r
+        * messages defined in the <code>SelectionListener</code> interface.\r
+        * <p>\r
+        * <code>widgetSelected</code> is called when the control is selected by the\r
+        * user. <code>widgetDefaultSelected</code> is not called.\r
+        * </p>\r
+        * \r
+        * @param listener the listener which should be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #removeSelectionListener\r
+        * @see SelectionEvent\r
+        */\r
+       public void addSelectionListener(final SelectionListener listener) {\r
+               this.checkWidget();\r
+               if (listener == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               this.listOfSelectionListeners.add(listener);\r
+       }\r
+\r
+       /**\r
+        * Removes the listener from the collection of listeners who will be\r
+        * notified when the control is selected by the user.\r
+        * \r
+        * @param listener the listener which should no longer be notified\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        * \r
+        * @see SelectionListener\r
+        * @see #addSelectionListener\r
+        */\r
+       public void removeSelectionListener(final SelectionListener listener) {\r
+               this.checkWidget();\r
+               if (listener == null) {\r
+                       SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
+               }\r
+               this.listOfSelectionListeners.remove(listener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)\r
+        */\r
+       @Override\r
+       public Point computeSize(final int wHint, final int hHint, final boolean changed) {\r
+               this.checkWidget();\r
+               boolean disposeGC = false;\r
+               if (this.gc == null) {\r
+                       this.gc = new GC(this);\r
+                       disposeGC = true;\r
+               }\r
+\r
+               final Point buttonSize = this.computeButtonSize();\r
+               int width = buttonSize.x;\r
+               int height = buttonSize.y;\r
+\r
+               if (this.text != null && this.text.trim().length() > 0) {\r
+                       final Point textSize = this.gc.textExtent(this.text);\r
+                       width += textSize.x + this.gap + 1;\r
+               }\r
+\r
+               width += 4;\r
+               height += 6;\r
+\r
+               if (disposeGC) {\r
+                       this.gc.dispose();\r
+               }\r
+\r
+               return new Point(width, height);\r
+       }\r
+\r
+       /**\r
+        * @return the selection state of the button\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public boolean getSelection() {\r
+               this.checkWidget();\r
+               return this.selection;\r
+       }\r
+\r
+       /**\r
+        * @param selection the selection state of the button\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setSelection(final boolean selection) {\r
+               this.checkWidget();\r
+               this.selection = selection;\r
+       }\r
+\r
+       /**\r
+        * @return the text used to display the selection\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public String getTextForSelect() {\r
+               this.checkWidget();\r
+               return this.textForSelect;\r
+       }\r
+\r
+       /**\r
+        * @param textForSelect the text used to display the selection\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setTextForSelect(final String textForSelect) {\r
+               this.checkWidget();\r
+               this.textForSelect = textForSelect;\r
+       }\r
+\r
+       /**\r
+        * @return the text used to display the unselected option\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public String getTextForUnselect() {\r
+               this.checkWidget();\r
+               return this.textForUnselect;\r
+       }\r
+\r
+       /**\r
+        * @param textForUnselect the text used to display the unselected option\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setTextForUnselect(final String textForUnselect) {\r
+               this.checkWidget();\r
+               this.textForUnselect = textForUnselect;\r
+       }\r
+\r
+       /**\r
+        * @return the text displayed in the widget\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public String getText() {\r
+               this.checkWidget();\r
+               return this.text;\r
+       }\r
+\r
+       /**\r
+        * @param the text displayed in the widget\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setText(final String text) {\r
+               this.checkWidget();\r
+               this.text = text;\r
+       }\r
+\r
+       /**\r
+        * @return the round flag\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public boolean isRound() {\r
+               this.checkWidget();\r
+               return this.round;\r
+       }\r
+\r
+       /**\r
+        * @param round the round flag to set. If true, the widget is composed of\r
+        *            round rectangle instead of rectangles\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setRound(final boolean round) {\r
+               this.checkWidget();\r
+               this.round = round;\r
+       }\r
+\r
+       /**\r
+        * @return the border's color. If null, no border is displayed\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getBorderColor() {\r
+               this.checkWidget();\r
+               return this.borderColor;\r
+       }\r
+\r
+       /**\r
+        * @param borderColor the border's color. If null, no border is displayed.\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setBorderColor(final Color borderColor) {\r
+               this.checkWidget();\r
+               this.borderColor = borderColor;\r
+       }\r
+\r
+       /**\r
+        * @return the focus color. If null, no focus effect is displayed.\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getFocusColor() {\r
+               this.checkWidget();\r
+               return this.focusColor;\r
+       }\r
+\r
+       /**\r
+        * @param focusColor the focus color to set. If null, no focus effect is\r
+        *            displayed.\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setFocusColor(final Color focusColor) {\r
+               this.checkWidget();\r
+               this.focusColor = focusColor;\r
+       }\r
+\r
+       /**\r
+        * @return the foreground color of the left part of the widget (selection is\r
+        *         on)\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getSelectedForegroundColor() {\r
+               this.checkWidget();\r
+               return this.selectedForegroundColor;\r
+       }\r
+\r
+       /**\r
+        * @param the foreground color of the left part of the widget (selection is\r
+        *            on)\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setSelectedForegroundColor(final Color selectedForegroundColor) {\r
+               this.checkWidget();\r
+               this.selectedForegroundColor = selectedForegroundColor;\r
+       }\r
+\r
+       /**\r
+        * @return the background color of the left part of the widget (selection is\r
+        *         on)\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getSelectedBackgroundColor() {\r
+               this.checkWidget();\r
+               return this.selectedBackgroundColor;\r
+       }\r
+\r
+       /**\r
+        * @param the background color of the left part of the widget (selection is\r
+        *            on)\r
+        */\r
+       public void setSelectedBackgroundColor(final Color selectedBackgroundColor) {\r
+               this.checkWidget();\r
+               this.selectedBackgroundColor = selectedBackgroundColor;\r
+       }\r
+\r
+       /**\r
+        * @return the foreground color of the left part of the widget (selection is\r
+        *         on)\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getUnselectedForegroundColor() {\r
+               this.checkWidget();\r
+               return this.unselectedForegroundColor;\r
+       }\r
+\r
+       /**\r
+        * @param unselectedForegroundColor the foreground color of the left part of\r
+        *            the widget (selection is on)\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setUnselectedForegroundColor(final Color unselectedForegroundColor) {\r
+               this.checkWidget();\r
+               this.unselectedForegroundColor = unselectedForegroundColor;\r
+       }\r
+\r
+       /**\r
+        * @return the background color of the left part of the widget (selection is\r
+        *         on)\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getUnselectedBackgroundColor() {\r
+               this.checkWidget();\r
+               return this.unselectedBackgroundColor;\r
+       }\r
+\r
+       /**\r
+        * @param unselectedBackgroundColor the background color of the left part of\r
+        *            the widget (selection is on)\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setUnselectedBackgroundColor(final Color unselectedBackgroundColor) {\r
+               this.checkWidget();\r
+               this.unselectedBackgroundColor = unselectedBackgroundColor;\r
+       }\r
+\r
+       /**\r
+        * @return the border color of the switch button\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getButtonBorderColor() {\r
+               this.checkWidget();\r
+               return this.buttonBorderColor;\r
+       }\r
+\r
+       /**\r
+        * @param buttonBorderColor the border color of the switch button\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setButtonBorderColor(final Color buttonBorderColor) {\r
+               this.checkWidget();\r
+               this.buttonBorderColor = buttonBorderColor;\r
+       }\r
+\r
+       /**\r
+        * @return the first color of the toggle button\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getButtonBackgroundColor1() {\r
+               this.checkWidget();\r
+               return this.buttonBackgroundColor1;\r
+       }\r
+\r
+       /**\r
+        * @param buttonBackgroundColor1 the first color of the toggle button\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setButtonBackgroundColor1(final Color buttonBackgroundColor1) {\r
+               this.checkWidget();\r
+               this.buttonBackgroundColor1 = buttonBackgroundColor1;\r
+       }\r
+\r
+       /**\r
+        * @return the second color of the toggle button\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Color getButtonBackgroundColor2() {\r
+               this.checkWidget();\r
+               return this.buttonBackgroundColor2;\r
+       }\r
+\r
+       /**\r
+        * @param buttonBackgroundColor2 the second color of the toggle button\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setButtonBackgroundColor2(final Color buttonBackgroundColor2) {\r
+               this.checkWidget();\r
+               this.buttonBackgroundColor2 = buttonBackgroundColor2;\r
+       }\r
+\r
+       /**\r
+        * @return the gap value\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public int getGap() {\r
+               this.checkWidget();\r
+               return this.gap;\r
+       }\r
+\r
+       /**\r
+        * @param gap the gap value to set\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setGap(final int gap) {\r
+               this.checkWidget();\r
+               this.gap = gap;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/textAssist/TextAssist.java b/org.tizen.common.externals/src/org/mihalis/opal/textAssist/TextAssist.java
new file mode 100755 (executable)
index 0000000..08bcebc
--- /dev/null
@@ -0,0 +1,694 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     IBM Corporation - initial API and implementation (Snippet 320)\r
+ *     Laurent CARON (laurent.caron@gmail.com) - Make a widget from the snippet\r
+ *******************************************************************************/\r
+package org.mihalis.opal.textAssist;\r
+\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.events.VerifyListener;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.swt.widgets.Widget;\r
+\r
+/**\r
+ * Instances of this class are selectable user interface objects that allow the\r
+ * user to enter and modify text. The difference with the Text widget is that\r
+ * when the user types something, some propositions are displayed.\r
+ * \r
+ * @see org.eclipse.swt.widgets.Text\r
+ */\r
+public class TextAssist extends Composite {\r
+\r
+       private final Text text;\r
+       private final Shell popup;\r
+       private final Table table;\r
+       private TextAssistContentProvider contentProvider;\r
+       private int numberOfLines;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * @param contentProvider the content provider\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                <li>ERROR_INVALID_SUBCLASS - if this class is not an\r
+        *                allowed subclass</li>\r
+        *                </ul>\r
+        * \r
+        * @see SWT#SINGLE\r
+        * @see SWT#MULTI\r
+        * @see SWT#READ_ONLY\r
+        * @see SWT#WRAP\r
+        * @see SWT#LEFT\r
+        * @see SWT#RIGHT\r
+        * @see SWT#CENTER\r
+        * @see SWT#PASSWORD\r
+        * @see SWT#SEARCH\r
+        * @see SWT#ICON_SEARCH\r
+        * @see SWT#ICON_CANCEL\r
+        * @see Widget#checkSubclass\r
+        * @see Widget#getStyle\r
+        */\r
+       public TextAssist(final Composite parent, final int style, final TextAssistContentProvider contentProvider) {\r
+               super(parent, style);\r
+               this.contentProvider = contentProvider;\r
+               this.contentProvider.setTextAssist(this);\r
+\r
+               this.setLayout(new FillLayout());\r
+               this.numberOfLines = 10;\r
+               this.text = new Text(this, style);\r
+               this.popup = new Shell(this.getDisplay(), SWT.ON_TOP);\r
+               this.popup.setLayout(new FillLayout());\r
+               this.table = new Table(this.popup, SWT.SINGLE);\r
+\r
+               this.text.addListener(SWT.KeyDown, createKeyDownListener());\r
+               this.text.addListener(SWT.Modify, createModifyListener());\r
+               this.text.addListener(SWT.FocusOut, createFocusOutListener());\r
+\r
+               this.table.addListener(SWT.DefaultSelection, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               TextAssist.this.text.setText(TextAssist.this.table.getSelection()[0].getText());\r
+                               TextAssist.this.popup.setVisible(false);\r
+                       }\r
+               });\r
+               this.table.addListener(SWT.KeyDown, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               if (event.keyCode == SWT.ESC) {\r
+                                       TextAssist.this.popup.setVisible(false);\r
+                               }\r
+                       }\r
+               });\r
+\r
+               this.table.addListener(SWT.FocusOut, createFocusOutListener());\r
+\r
+               getShell().addListener(SWT.Move, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               TextAssist.this.popup.setVisible(false);\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * @return a listener for the keydown event\r
+        */\r
+       private Listener createKeyDownListener() {\r
+               return new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               switch (event.keyCode) {\r
+                               case SWT.ARROW_DOWN:\r
+                                       int index = (TextAssist.this.table.getSelectionIndex() + 1) % TextAssist.this.table.getItemCount();\r
+                                       TextAssist.this.table.setSelection(index);\r
+                                       event.doit = false;\r
+                                       break;\r
+                               case SWT.ARROW_UP:\r
+                                       index = TextAssist.this.table.getSelectionIndex() - 1;\r
+                                       if (index < 0) {\r
+                                               index = TextAssist.this.table.getItemCount() - 1;\r
+                                       }\r
+                                       TextAssist.this.table.setSelection(index);\r
+                                       event.doit = false;\r
+                                       break;\r
+                               case SWT.CR:\r
+                                       if (TextAssist.this.popup.isVisible() && TextAssist.this.table.getSelectionIndex() != -1) {\r
+                                               TextAssist.this.text.setText(TextAssist.this.table.getSelection()[0].getText());\r
+                                               TextAssist.this.popup.setVisible(false);\r
+                                       }\r
+                                       break;\r
+                               case SWT.ESC:\r
+                                       TextAssist.this.popup.setVisible(false);\r
+                                       break;\r
+                                       \r
+                               default:\r
+                                   break;\r
+                               }\r
+                       }\r
+               };\r
+       }\r
+\r
+       /**\r
+        * @return a listener for the modify event\r
+        */\r
+       private Listener createModifyListener() {\r
+               return new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               final String string = TextAssist.this.text.getText();\r
+                               if (string.length() == 0) {\r
+                                       TextAssist.this.popup.setVisible(false);\r
+                                       return;\r
+                               }\r
+\r
+                               List<String> values = TextAssist.this.contentProvider.getContent(string);\r
+                               if (values == null || values.isEmpty()) {\r
+                                       TextAssist.this.popup.setVisible(false);\r
+                                       return;\r
+                               }\r
+\r
+                               if (values.size() > TextAssist.this.numberOfLines) {\r
+                                       values = values.subList(0, TextAssist.this.numberOfLines);\r
+                               }\r
+\r
+                               TextAssist.this.table.removeAll();\r
+                               final int numberOfRows = Math.min(values.size(), TextAssist.this.numberOfLines);\r
+                               for (int i = 0; i < numberOfRows; i++) {\r
+                                       final TableItem tableItem = new TableItem(TextAssist.this.table, SWT.NONE);\r
+                                       tableItem.setText(values.get(i));\r
+                               }\r
+\r
+                               final Point point = TextAssist.this.text.toDisplay(TextAssist.this.text.getLocation().x, TextAssist.this.text.getSize().y + TextAssist.this.text.getBorderWidth() - 3);\r
+                               int x = point.x;\r
+                               int y = point.y;\r
+\r
+                               final Rectangle displayRect = getMonitor().getClientArea();\r
+                               final Rectangle parentRect = getDisplay().map(getParent(), null, getBounds());\r
+                               TextAssist.this.popup.pack();\r
+                               final int width = TextAssist.this.popup.getBounds().width;\r
+                               final int height = TextAssist.this.popup.getBounds().height;\r
+\r
+                               if (y + height > displayRect.y + displayRect.height) {\r
+                                       y = parentRect.y - height;\r
+                               }\r
+                               if (x + width > displayRect.x + displayRect.width) {\r
+                                       x = displayRect.x + displayRect.width - width;\r
+                               }\r
+\r
+                               TextAssist.this.popup.setLocation(x, y);\r
+                               TextAssist.this.popup.setVisible(true);\r
+\r
+                       }\r
+               };\r
+       }\r
+\r
+       /**\r
+        * @return a listener for the FocusOut event\r
+        */\r
+       private Listener createFocusOutListener() {\r
+               return new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               /* async is needed to wait until focus reaches its new Control */\r
+                               TextAssist.this.getDisplay().asyncExec(new Runnable() {\r
+                                       @Override\r
+                                       public void run() {\r
+                                               if (TextAssist.this.getDisplay().isDisposed()) {\r
+                                                       return;\r
+                                               }\r
+                                               final Control control = TextAssist.this.getDisplay().getFocusControl();\r
+                                               if (control == null || control != TextAssist.this.text && control != TextAssist.this.table) {\r
+                                                       TextAssist.this.popup.setVisible(false);\r
+                                               }\r
+                                       }\r
+                               });\r
+                       }\r
+               };\r
+       }\r
+\r
+       /**\r
+        * @return the contentProvider\r
+        */\r
+       public TextAssistContentProvider getContentProvider() {\r
+               checkWidget();\r
+               return this.contentProvider;\r
+       }\r
+\r
+       /**\r
+        * @param contentProvider the contentProvider to set\r
+        */\r
+       public void setContentProvider(final TextAssistContentProvider contentProvider) {\r
+               checkWidget();\r
+               this.contentProvider = contentProvider;\r
+       }\r
+\r
+       /**\r
+        * @return the numberOfLines\r
+        */\r
+       public int getNumberOfLines() {\r
+               checkWidget();\r
+               return this.numberOfLines;\r
+       }\r
+\r
+       /**\r
+        * @param numberOfLines the numberOfLines to set\r
+        */\r
+       public void setNumberOfLines(final int numberOfLines) {\r
+               checkWidget();\r
+               this.numberOfLines = numberOfLines;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#addModifyListener(org.eclipse.swt.events.ModifyListener)\r
+        */\r
+       public void addModifyListener(final ModifyListener listener) {\r
+               checkWidget();\r
+               this.text.addModifyListener(listener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#addSelectionListener(org.eclipse.swt.events.SelectionListener)\r
+        */\r
+       public void addSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               this.text.addSelectionListener(listener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#addVerifyListener(org.eclipse.swt.events.VerifyListener)\r
+        */\r
+       public void addVerifyListener(final VerifyListener listener) {\r
+               checkWidget();\r
+               this.text.addVerifyListener(listener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#append(java.lang.String)\r
+        */\r
+       public void append(final String string) {\r
+               checkWidget();\r
+               this.text.append(string);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#clearSelection()\r
+        */\r
+       public void clearSelection() {\r
+               checkWidget();\r
+               this.text.clearSelection();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#computeSize(int, int, boolean)\r
+        */\r
+       @Override\r
+       public Point computeSize(final int wHint, final int hHint, final boolean changed) {\r
+               checkWidget();\r
+               return this.text.computeSize(wHint, hHint, changed);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#computeTrim(int, int, int, int)\r
+        */\r
+       @Override\r
+       public Rectangle computeTrim(final int x, final int y, final int width, final int height) {\r
+               checkWidget();\r
+               return super.computeTrim(x, y, width, height);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#copy()\r
+        */\r
+       public void copy() {\r
+               checkWidget();\r
+               this.text.copy();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#cut()\r
+        */\r
+       public void cut() {\r
+               checkWidget();\r
+               this.text.cut();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getCaretLineNumber()\r
+        */\r
+       public int getCaretLineNumber() {\r
+               checkWidget();\r
+               return this.text.getCaretLineNumber();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getCaretLocation()\r
+        */\r
+       public Point getCaretLocation() {\r
+               checkWidget();\r
+               return this.text.getCaretLocation();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getCaretPosition()\r
+        */\r
+       public int getCaretPosition() {\r
+               checkWidget();\r
+               return this.text.getCaretPosition();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getCharCount()\r
+        */\r
+       public int getCharCount() {\r
+               checkWidget();\r
+               return this.text.getCharCount();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getDoubleClickEnabled()\r
+        */\r
+       public boolean getDoubleClickEnabled() {\r
+               checkWidget();\r
+               return this.text.getDoubleClickEnabled();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getEchoChar()\r
+        */\r
+       public char getEchoChar() {\r
+               checkWidget();\r
+               return this.text.getEchoChar();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getEditable()\r
+        */\r
+       public boolean getEditable() {\r
+               checkWidget();\r
+               return this.text.getEditable();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getLineCount()\r
+        */\r
+       public int getLineCount() {\r
+               checkWidget();\r
+               return this.text.getLineCount();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getLineDelimiter()\r
+        */\r
+       public String getLineDelimiter() {\r
+               checkWidget();\r
+               return this.text.getLineDelimiter();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getLineHeight()\r
+        */\r
+       public int getLineHeight() {\r
+               checkWidget();\r
+               return this.text.getLineHeight();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getMessage()\r
+        */\r
+       public String getMessage() {\r
+               checkWidget();\r
+               return this.text.getMessage();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getOrientation()\r
+        */\r
+       public int getOrientation() {\r
+               checkWidget();\r
+               return this.text.getOrientation();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getSelection()\r
+        */\r
+       public Point getSelection() {\r
+               checkWidget();\r
+               return this.text.getSelection();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getSelectionCount()\r
+        */\r
+       public int getSelectionCount() {\r
+               checkWidget();\r
+               return this.text.getSelectionCount();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getSelectionText()\r
+        */\r
+       public String getSelectionText() {\r
+               checkWidget();\r
+               return this.text.getSelectionText();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getTabs()\r
+        */\r
+       public int getTabs() {\r
+               checkWidget();\r
+               return this.text.getTabs();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getText()\r
+        */\r
+       public String getText() {\r
+               checkWidget();\r
+               return this.text.getText();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getText(int, int)\r
+        */\r
+       public String getText(final int start, final int end) {\r
+               checkWidget();\r
+               return this.text.getText(start, end);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getTextLimit()\r
+        */\r
+       public int getTextLimit() {\r
+               checkWidget();\r
+               return this.text.getTextLimit();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getTopIndex()\r
+        */\r
+       public int getTopIndex() {\r
+               checkWidget();\r
+               return this.text.getTopIndex();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#getTopPixel()\r
+        */\r
+       public int getTopPixel() {\r
+               checkWidget();\r
+               return this.text.getTopPixel();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#insert(java.lang.String)\r
+        */\r
+       public void insert(final String string) {\r
+               checkWidget();\r
+               this.text.insert(string);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#paste()\r
+        */\r
+       public void paste() {\r
+               checkWidget();\r
+               this.text.paste();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#removeModifyListener(org.eclipse.swt.events.ModifyListener)\r
+        */\r
+       public void removeModifyListener(final ModifyListener listener) {\r
+               checkWidget();\r
+               this.text.removeModifyListener(listener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#removeSelectionListener(org.eclipse.swt.events.SelectionListener)\r
+        */\r
+       public void removeSelectionListener(final SelectionListener listener) {\r
+               checkWidget();\r
+               this.text.removeSelectionListener(listener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#removeVerifyListener(org.eclipse.swt.events.VerifyListener)\r
+        */\r
+       public void removeVerifyListener(final VerifyListener listener) {\r
+               checkWidget();\r
+               this.text.removeVerifyListener(listener);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#selectAll()\r
+        */\r
+       public void selectAll() {\r
+               checkWidget();\r
+               this.text.selectAll();\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setDoubleClickEnabled(boolean)\r
+        */\r
+       public void setDoubleClickEnabled(final boolean doubleClick) {\r
+               checkWidget();\r
+               this.text.setDoubleClickEnabled(doubleClick);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setEchoChar(char)\r
+        */\r
+       public void setEchoChar(final char echo) {\r
+               checkWidget();\r
+               this.text.setEchoChar(echo);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setEditable(boolean)\r
+        */\r
+       public void setEditable(final boolean editable) {\r
+               checkWidget();\r
+               this.text.setEditable(editable);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setFont(org.eclipse.swt.graphics.Font)\r
+        */\r
+       @Override\r
+       public void setFont(final Font font) {\r
+               checkWidget();\r
+               this.text.setFont(font);\r
+               this.table.setFont(font);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setMessage(java.lang.String)\r
+        */\r
+       public void setMessage(final String string) {\r
+               checkWidget();\r
+               this.text.setMessage(string);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setOrientation(int)\r
+        */\r
+       public void setOrientation(final int orientation) {\r
+               checkWidget();\r
+               this.text.setOrientation(orientation);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setRedraw(boolean)\r
+        */\r
+       @Override\r
+       public void setRedraw(final boolean redraw) {\r
+               checkWidget();\r
+               this.text.setRedraw(redraw);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setSelection(int, int)\r
+        */\r
+       public void setSelection(final int start, final int end) {\r
+               checkWidget();\r
+               this.text.setSelection(start, end);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setSelection(int)\r
+        */\r
+       public void setSelection(final int start) {\r
+               checkWidget();\r
+               this.text.setSelection(start);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setSelection(org.eclipse.swt.graphics.Point)\r
+        */\r
+       public void setSelection(final Point selection) {\r
+               checkWidget();\r
+               this.text.setSelection(selection);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setTabs(int)\r
+        */\r
+       public void setTabs(final int tabs) {\r
+               checkWidget();\r
+               this.text.setTabs(tabs);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setText(java.lang.String)\r
+        */\r
+       public void setText(final String text) {\r
+               checkWidget();\r
+               this.text.setText(text);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setTextLimit(int)\r
+        */\r
+       public void setTextLimit(final int textLimit) {\r
+               checkWidget();\r
+               this.text.setTextLimit(textLimit);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#setTopIndex(int)\r
+        */\r
+       public void setTopIndex(final int topIndex) {\r
+               checkWidget();\r
+               this.text.setTopIndex(topIndex);\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Text#showSelection()\r
+        */\r
+       public void showSelection() {\r
+               checkWidget();\r
+               this.text.showSelection();\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/textAssist/TextAssistContentProvider.java b/org.tizen.common.externals/src/org/mihalis/opal/textAssist/TextAssistContentProvider.java
new file mode 100644 (file)
index 0000000..313fb68
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.textAssist;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * This class is a content provider for the TextAssist widget. When the user\r
+ * types something, an instance returns an arraylist of proposition based on the\r
+ * typed text.\r
+ * \r
+ */\r
+public abstract class TextAssistContentProvider {\r
+       private TextAssist textAssist;\r
+\r
+       /**\r
+        * Provides the content\r
+        * \r
+        * @param entry text typed by the user\r
+        * @return an array list of String that contains propositions for the entry\r
+        *         typed by the user\r
+        */\r
+       public abstract List<String> getContent(final String entry);\r
+\r
+       /**\r
+        * @param textAssist the textAssist to set\r
+        */\r
+       protected void setTextAssist(final TextAssist textAssist) {\r
+               this.textAssist = textAssist;\r
+       }\r
+\r
+       /**\r
+        * @return the max number of propositions.\r
+        */\r
+       protected int getMaxNumberOfLines() {\r
+               return this.textAssist.getNumberOfLines();\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/tipOfTheDay/TipOfTheDay.java b/org.tizen.common.externals/src/org/mihalis/opal/tipOfTheDay/TipOfTheDay.java
new file mode 100755 (executable)
index 0000000..4ec53c7
--- /dev/null
@@ -0,0 +1,524 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation \r
+ *******************************************************************************/\r
+package org.mihalis.opal.tipOfTheDay;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Random;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.browser.Browser;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.FillLayout;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.mihalis.opal.header.Header;\r
+import org.mihalis.opal.utils.ResourceManager;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class are a "Tip of Day" box, which is composed of\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>A tip</b></dt>\r
+ * <dt><b>2 buttons to navigate between types</b></dt>\r
+ * <dt><b>A close button</b></dt>\r
+ * <dt><b>A checkbox "show tip on startup"</b></dt>\r
+ * <dd>(optional)</dd>\r
+ * <dt><b>A checkbox "remember the password"</b></dt>\r
+ * <dd>(optional)</dd>\r
+ * </dl>\r
+ * </p>\r
+ */\r
+public class TipOfTheDay {\r
+\r
+       /**\r
+        * Types of opal dialog\r
+        */\r
+       public enum TipStyle {\r
+               TWO_COLUMNS, TWO_COLUMNS_LARGE, HEADER\r
+       }\r
+\r
+       private final List<String> tips;\r
+       private boolean displayShowOnStartup = true;\r
+       private boolean showOnStartup = true;\r
+       private Shell shell;\r
+       private Button close;\r
+       private int index;\r
+       private Browser tipArea;\r
+       private String fontName;\r
+       private TipStyle style;\r
+       private Image image;\r
+\r
+       /**\r
+        * Constructor\r
+        */\r
+       public TipOfTheDay() {\r
+               this.tips = new ArrayList<String>();\r
+               this.index = -1;\r
+               final Font temp = Display.getDefault().getSystemFont();\r
+               final FontData[] fontData = temp.getFontData();\r
+               if (fontData != null && fontData.length > 0) {\r
+                       this.fontName = fontData[0].getName();\r
+               } else {\r
+                       this.fontName = "Arial";\r
+               }\r
+               this.style = TipStyle.TWO_COLUMNS;\r
+\r
+       }\r
+\r
+       /**\r
+        * Open the "tip of the day" box\r
+        * \r
+        * @param parent the parent shell\r
+        */\r
+       public void open(final Shell parent) {\r
+               if (this.index == -1) {\r
+                       this.index = new Random().nextInt(this.tips.size());\r
+               }\r
+               buildShell(parent);\r
+               if (this.style == TipStyle.HEADER) {\r
+                       buildHeader();\r
+               } else {\r
+                       buildLeftColumn();\r
+               }\r
+               buildTip();\r
+               buildButtons();\r
+               openShell();\r
+       }\r
+\r
+       /**\r
+        * Build the shell\r
+        * \r
+        * @param parent parent shell\r
+        */\r
+       private void buildShell(final Shell parent) {\r
+               this.shell = new Shell(parent, SWT.SYSTEM_MODAL | SWT.TITLE | SWT.BORDER | SWT.CLOSE | SWT.RESIZE);\r
+               this.shell.setText(ResourceManager.getLabel(ResourceManager.TIP_OF_THE_DAY));\r
+               this.shell.setLayout(new GridLayout(this.style == TipStyle.HEADER ? 1 : 2, false));\r
+\r
+               this.shell.addListener(SWT.Traverse, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               switch (event.detail) {\r
+                               case SWT.TRAVERSE_ESCAPE:\r
+                                       TipOfTheDay.this.shell.dispose();\r
+                                       event.detail = SWT.TRAVERSE_NONE;\r
+                                       event.doit = false;\r
+                                       break;\r
+                               default:\r
+                                   break;\r
+                               }\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Build the header\r
+        */\r
+       private void buildHeader() {\r
+               final Header header = new Header(this.shell, SWT.NONE);\r
+               final GridData gd = new GridData(GridData.FILL, GridData.BEGINNING, true, false);\r
+               gd.heightHint = 80;\r
+               header.setLayoutData(gd);\r
+               header.setTitle(ResourceManager.getLabel(ResourceManager.DID_YOU_KNOW));\r
+               if (this.image == null) {\r
+                       final Image img = SWTGraphicUtil.createImage("images/light2.png");\r
+                       header.setImage(img);\r
+                       this.shell.addListener(SWT.Dispose, new Listener() {\r
+\r
+                               @Override\r
+                               public void handleEvent(final Event event) {\r
+                                       img.dispose();\r
+\r
+                               }\r
+                       });\r
+               } else {\r
+                       header.setImage(this.image);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Build the left column\r
+        */\r
+       private void buildLeftColumn() {\r
+               final Composite composite = new Composite(this.shell, SWT.NONE);\r
+               int numberOfRows = 1;\r
+               if (this.style == TipStyle.TWO_COLUMNS_LARGE) {\r
+                       numberOfRows = this.displayShowOnStartup ? 5 : 4;\r
+               }\r
+\r
+               final GridData gd = new GridData(GridData.FILL, GridData.BEGINNING, false, true, 1, numberOfRows);\r
+               composite.setLayoutData(gd);\r
+               final FillLayout compositeLayout = new FillLayout();\r
+               compositeLayout.marginWidth = 2;\r
+               composite.setLayout(compositeLayout);\r
+               final Label label = new Label(composite, SWT.NONE);\r
+               if (this.image == null) {\r
+                       final Image img = SWTGraphicUtil.createImage("images/light1.png");\r
+                       label.setImage(img);\r
+                       this.shell.addListener(SWT.Dispose, new Listener() {\r
+\r
+                               @Override\r
+                               public void handleEvent(final Event event) {\r
+                                       img.dispose();\r
+                               }\r
+                       });\r
+               } else {\r
+                       label.setImage(this.image);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Build the tip area\r
+        */\r
+       private void buildTip() {\r
+               if (this.style == TipStyle.TWO_COLUMNS) {\r
+                       final Group group = new Group(this.shell, SWT.NONE);\r
+                       final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true);\r
+                       gd.widthHint = 300;\r
+                       gd.heightHint = 120;\r
+                       group.setLayoutData(gd);\r
+                       group.setText(ResourceManager.getLabel(ResourceManager.DID_YOU_KNOW));\r
+                       final FillLayout fillLayout = new FillLayout();\r
+                       fillLayout.marginWidth = 15;\r
+                       group.setLayout(fillLayout);\r
+\r
+                       this.tipArea = new Browser(group, SWT.BORDER);\r
+               } else if (this.style == TipStyle.TWO_COLUMNS_LARGE) {\r
+                       final Label title = new Label(this.shell, SWT.NONE);\r
+                       final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, false);\r
+                       gd.verticalIndent = 15;\r
+                       title.setLayoutData(gd);\r
+                       final Font tempFont = SWTGraphicUtil.buildFontFrom(title, SWT.BOLD, 16);\r
+                       title.setText(ResourceManager.getLabel(ResourceManager.TIP_OF_THE_DAY));\r
+                       title.setFont(tempFont);\r
+                       this.shell.addListener(SWT.Dispose, new Listener() {\r
+\r
+                               @Override\r
+                               public void handleEvent(final Event event) {\r
+                                       tempFont.dispose();\r
+                               }\r
+                       });\r
+                       final Label separator = new Label(this.shell, SWT.SEPARATOR | SWT.HORIZONTAL);\r
+                       separator.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));\r
+\r
+                       this.tipArea = new Browser(this.shell, SWT.BORDER);\r
+                       final GridData gdTipArea = new GridData(GridData.FILL, GridData.FILL, true, true);\r
+                       gdTipArea.heightHint = 120;\r
+                       this.tipArea.setLayoutData(gdTipArea);\r
+\r
+               } else {\r
+                       this.tipArea = new Browser(this.shell, SWT.BORDER);\r
+                       final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true);\r
+                       gd.heightHint = 120;\r
+                       this.tipArea.setLayoutData(gd);\r
+               }\r
+               fillTipArea();\r
+\r
+       }\r
+\r
+       /**\r
+        * Fill the tip area with the selected tip\r
+        */\r
+       private void fillTipArea() {\r
+               this.tipArea.setText("<html><body bgcolor=\"#ffffff\" text=\"#000000\"><p style=\"font-family:" + this.fontName + ";font-size=12px\">" //\r
+                               + this.tips.get(this.index) + "</p></body></html>");\r
+       }\r
+\r
+       /**\r
+        * Build the button (checkbox, previous tip, next tip, close)\r
+        */\r
+       private void buildButtons() {\r
+               final Composite composite = new Composite(this.shell, SWT.NONE);\r
+               int numberOfColumns;\r
+               if (this.style == TipStyle.HEADER) {\r
+                       numberOfColumns = 1;\r
+               } else if (this.style == TipStyle.TWO_COLUMNS) {\r
+                       numberOfColumns = 2;\r
+               } else {\r
+                       numberOfColumns = 1;\r
+               }\r
+\r
+               final GridData gd = new GridData(GridData.FILL, GridData.BEGINNING, false, false, numberOfColumns, 1);\r
+               composite.setLayoutData(gd);\r
+               final GridLayout gridLayout = new GridLayout();\r
+               gridLayout.marginWidth = 2;\r
+               if (this.style == TipStyle.TWO_COLUMNS_LARGE) {\r
+                       composite.setLayout(new GridLayout(3, false));\r
+               } else {\r
+                       composite.setLayout(new GridLayout(this.displayShowOnStartup ? 4 : 3, false));\r
+               }\r
+\r
+               final GridData gridShowOnStartup, gridPrevious, gridNext, gridClose;\r
+               if (this.style == TipStyle.TWO_COLUMNS_LARGE) {\r
+                       gridShowOnStartup = new GridData(GridData.BEGINNING, GridData.BEGINNING, true, false, 3, 1);\r
+\r
+                       gridPrevious = new GridData(GridData.END, GridData.CENTER, true, false);\r
+                       gridPrevious.widthHint = 120;\r
+\r
+                       gridNext = new GridData(GridData.CENTER, GridData.CENTER, false, false);\r
+                       gridNext.widthHint = 120;\r
+\r
+                       gridClose = new GridData(GridData.BEGINNING, GridData.CENTER, true, false);\r
+                       gridClose.widthHint = 120;\r
+\r
+               } else {\r
+                       gridShowOnStartup = new GridData(GridData.BEGINNING, GridData.CENTER, true, false);\r
+\r
+                       gridPrevious = new GridData(GridData.END, GridData.CENTER, this.showOnStartup ? false : true, false);\r
+                       gridPrevious.widthHint = 120;\r
+\r
+                       gridNext = new GridData(GridData.FILL, GridData.CENTER, false, false);\r
+                       gridNext.widthHint = 120;\r
+\r
+                       gridClose = new GridData(GridData.FILL, GridData.CENTER, false, false);\r
+                       gridClose.widthHint = 120;\r
+               }\r
+\r
+               if (this.displayShowOnStartup) {\r
+                       buildShowOnStartup(composite, gridShowOnStartup);\r
+               }\r
+\r
+               buildPreviousButton(composite, gridPrevious);\r
+               buildNextButton(composite, gridNext);\r
+               buildCloseButton(composite, gridClose);\r
+\r
+       }\r
+\r
+       /**\r
+        * Build the "show on startup" checkbox\r
+        * \r
+        * @param composite parent composite\r
+        * @param gridData associated grid data\r
+        */\r
+       private void buildShowOnStartup(final Composite composite, final GridData gridData) {\r
+               final Button checkBox = new Button(composite, SWT.CHECK);\r
+               checkBox.setLayoutData(gridData);\r
+               checkBox.setText(ResourceManager.getLabel(ResourceManager.SHOW_TIP_AT_STARTUP));\r
+               checkBox.setSelection(this.showOnStartup);\r
+               checkBox.addListener(SWT.Selection, new Listener() {\r
+\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               TipOfTheDay.this.showOnStartup = checkBox.getSelection();\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Build the "previous tip" button\r
+        * \r
+        * @param composite parent composite\r
+        * @param gridData associated grid data\r
+        */\r
+       private void buildPreviousButton(final Composite composite, final GridData gridData) {\r
+               final Button previous = new Button(composite, SWT.PUSH);\r
+               previous.setText(ResourceManager.getLabel(ResourceManager.PREVIOUS_TIP));\r
+               previous.setLayoutData(gridData);\r
+               previous.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               if (TipOfTheDay.this.index == 0) {\r
+                                       setIndex(TipOfTheDay.this.tips.size() - 1);\r
+                               } else {\r
+                                       setIndex(TipOfTheDay.this.index - 1);\r
+                               }\r
+                       }\r
+\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Build the "next tip" button\r
+        * \r
+        * @param composite parent composite\r
+        * @param gridData associated grid data\r
+        */\r
+       private void buildNextButton(final Composite composite, final GridData gridData) {\r
+               final Button next = new Button(composite, SWT.PUSH);\r
+               next.setText(ResourceManager.getLabel(ResourceManager.NEXT_TIP));\r
+\r
+               next.setLayoutData(gridData);\r
+               next.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               if (TipOfTheDay.this.index == TipOfTheDay.this.tips.size() - 1) {\r
+                                       setIndex(0);\r
+                               } else {\r
+                                       setIndex(TipOfTheDay.this.index + 1);\r
+                               }\r
+                       }\r
+\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Build the "close" button\r
+        * \r
+        * @param composite parent composite\r
+        * @param gridData associated grid data\r
+        */\r
+       private void buildCloseButton(final Composite composite, final GridData gridData) {\r
+               this.close = new Button(composite, SWT.PUSH);\r
+               this.close.setText(ResourceManager.getLabel(ResourceManager.CLOSE));\r
+\r
+               this.close.setLayoutData(gridData);\r
+               this.close.addSelectionListener(new SelectionAdapter() {\r
+\r
+                       /**\r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       @Override\r
+                       public void widgetSelected(final SelectionEvent e) {\r
+                               TipOfTheDay.this.shell.dispose();\r
+                       }\r
+\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Open the shell\r
+        */\r
+       private void openShell() {\r
+               this.shell.setDefaultButton(this.close);\r
+               this.shell.pack();\r
+               this.shell.open();\r
+               SWTGraphicUtil.centerShell(this.shell);\r
+\r
+               while (!this.shell.isDisposed()) {\r
+                       if (!this.shell.getDisplay().readAndDispatch()) {\r
+                               this.shell.getDisplay().sleep();\r
+                       }\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Add a tip\r
+        * \r
+        * @param tip tip to add\r
+        * @return the current object\r
+        */\r
+       public TipOfTheDay addTip(final String tip) {\r
+               this.tips.add(tip);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @return the image\r
+        */\r
+       public Image getImage() {\r
+               return this.image;\r
+       }\r
+\r
+       /**\r
+        * @return the index of the current tip\r
+        */\r
+       public int getIndex() {\r
+               return this.index;\r
+       }\r
+\r
+       /**\r
+        * @return the style of the window\r
+        */\r
+       public TipStyle getStyle() {\r
+               return this.style;\r
+       }\r
+\r
+       /**\r
+        * @return all the the tips\r
+        */\r
+       public List<String> getTips() {\r
+               return this.tips;\r
+       }\r
+\r
+       /**\r
+        * @return if <code>true</code>, the "Show On Startup" checkbox is displayed\r
+        */\r
+       public boolean isDisplayShowOnStartup() {\r
+               return this.displayShowOnStartup;\r
+       }\r
+\r
+       /**\r
+        * @return the value of the checkbox "Show On Startup"\r
+        */\r
+       public boolean isShowOnStartup() {\r
+               return this.showOnStartup;\r
+       }\r
+\r
+       /**\r
+        * @param if <code>true</code>, the checkbox "Show on startup" is displayed\r
+        */\r
+       public void setDisplayShowOnStartup(final boolean displayShowOnStartup) {\r
+               this.displayShowOnStartup = displayShowOnStartup;\r
+       }\r
+\r
+       /**\r
+        * @param index the index of the selected tip. By default, the tip is chosen\r
+        *            randomly\r
+        */\r
+       public void setIndex(final int index) {\r
+               if (index < 0 || index >= this.tips.size() || this.tips.get(index) == null) {\r
+                       throw new IllegalArgumentException("Index should be between 0 and " + (this.tips.size() - 1) + " (entered value:" + index + ")");\r
+               }\r
+\r
+               this.index = index;\r
+               if (this.tipArea != null && !this.tipArea.isDisposed()) {\r
+                       fillTipArea();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @param image the image to set\r
+        */\r
+       public void setImage(final Image image) {\r
+               this.image = image;\r
+       }\r
+\r
+       /**\r
+        * @param the value of the checkbox "Show on startup"\r
+        */\r
+       public void setShowOnStartup(final boolean showOnStartup) {\r
+               this.showOnStartup = showOnStartup;\r
+       }\r
+\r
+       /**\r
+        * @param style the style of the window\r
+        */\r
+       public void setStyle(final TipStyle style) {\r
+               this.style = style;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/titledSeparator/TitledSeparator.java b/org.tizen.common.externals/src/org/mihalis/opal/titledSeparator/TitledSeparator.java
new file mode 100644 (file)
index 0000000..12f708b
--- /dev/null
@@ -0,0 +1,314 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.titledSeparator;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Layout;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.mihalis.opal.utils.SWTGraphicUtil;\r
+\r
+/**\r
+ * Instances of this class provide a separator with a title and/or an image.\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>BORDER</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * </dl>\r
+ * </p>\r
+ */\r
+public class TitledSeparator extends Composite {\r
+\r
+       private int alignment;\r
+       private Image image;\r
+       private String text;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       public TitledSeparator(final Composite parent, final int style) {\r
+               super(parent, style);\r
+               this.alignment = SWT.LEFT;\r
+\r
+               final Color originalColor = new Color(getDisplay(), 0, 88, 150);\r
+               setForeground(originalColor);\r
+\r
+               final Font originalFont;\r
+               final FontData[] fontData = getFont().getFontData();\r
+               if (fontData != null && fontData.length > 0) {\r
+                       final FontData fd = fontData[0];\r
+                       fd.setStyle(SWT.BOLD);\r
+                       originalFont = new Font(getDisplay(), fd);\r
+                       setFont(originalFont);\r
+               } else {\r
+                       originalFont = null;\r
+               }\r
+\r
+               this.addListener(SWT.Resize, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               redrawComposite();\r
+                       }\r
+               });\r
+\r
+               this.addListener(SWT.Dispose, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event event) {\r
+                               SWTGraphicUtil.dispose(originalColor);\r
+                               SWTGraphicUtil.dispose(originalFont);\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * Redraw the composite\r
+        */\r
+       private void redrawComposite() {\r
+               // Dispose previous content\r
+               for (final Control c : this.getChildren()) {\r
+                       c.dispose();\r
+               }\r
+\r
+               int numberOfColumns = 1;\r
+\r
+               if (this.text != null) {\r
+                       numberOfColumns++;\r
+               }\r
+               if (this.image != null) {\r
+                       numberOfColumns++;\r
+               }\r
+\r
+               if (this.alignment == SWT.CENTER) {\r
+                       numberOfColumns++;\r
+               }\r
+\r
+               super.setLayout(new GridLayout(numberOfColumns, false));\r
+               createContent();\r
+       }\r
+\r
+       /**\r
+        * Create the content\r
+        */\r
+       private void createContent() {\r
+               switch (this.alignment) {\r
+               case SWT.CENTER:\r
+                       createSeparator();\r
+                       createTitle();\r
+                       break;\r
+               case SWT.LEFT:\r
+                       createTitle();\r
+                       createSeparator();\r
+                       break;\r
+               default:\r
+                       createSeparator();\r
+                       createTitle();\r
+                       break;\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Create a separator\r
+        */\r
+       private void createSeparator() {\r
+               final Label separator = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);\r
+               separator.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));\r
+               separator.setBackground(getBackground());\r
+       }\r
+\r
+       /**\r
+        * Create the title\r
+        */\r
+       private void createTitle() {\r
+\r
+               if (this.image != null) {\r
+                       final Label imageLabel = createLabel();\r
+                       imageLabel.setImage(this.image);\r
+               }\r
+\r
+               if (this.text != null && !this.text.trim().equals("")) {\r
+                       final Label textLabel = createLabel();\r
+                       textLabel.setText(this.text);\r
+\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * @return a SWT label\r
+        */\r
+       private Label createLabel() {\r
+               final Label label = new Label(this, SWT.NONE);\r
+               label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false));\r
+               label.setFont(getFont());\r
+               label.setForeground(getForeground());\r
+               label.setBackground(getBackground());\r
+               return label;\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#setLayout(org.eclipse.swt.widgets.Layout)\r
+        */\r
+       @Override\r
+       public void setLayout(final Layout layout) {\r
+               throw new UnsupportedOperationException("Not supported");\r
+       }\r
+\r
+       /**\r
+        * Returns a value which describes the position of the text or image in the\r
+        * receiver. The value will be one of <code>LEFT</code>, <code>RIGHT</code>\r
+        * or <code>CENTER</code>.\r
+        * \r
+        * @return the alignment\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+\r
+       public int getAlignment() {\r
+               checkWidget();\r
+               return this.alignment;\r
+       }\r
+\r
+       /**\r
+        * Returns the receiver's image if it has one, or null if it does not.\r
+        * \r
+        * @return the receiver's image\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public Image getImage() {\r
+               checkWidget();\r
+               return this.image;\r
+       }\r
+\r
+       /**\r
+        * Returns the receiver's text.\r
+        * \r
+        * @return the receiver's text\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public String getText() {\r
+               checkWidget();\r
+               return this.text;\r
+       }\r
+\r
+       /**\r
+        * Controls how text will be displayed in the receiver. The argument should\r
+        * be one of <code>LEFT</code>, <code>RIGHT</code> or <code>CENTER</code>.\r
+        * \r
+        * @param alignment the new alignment\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setAlignment(final int alignment) {\r
+               checkWidget();\r
+               this.alignment = alignment;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's image to the argument, which may be null indicating\r
+        * that no image should be displayed.\r
+        * \r
+        * @param image the image to display on the receiver (may be null)\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_INVALID_ARGUMENT - if the image has been\r
+        *                disposed</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setImage(final Image image) {\r
+               checkWidget();\r
+               this.image = image;\r
+       }\r
+\r
+       /**\r
+        * Sets the receiver's text.\r
+        * \r
+        * @param string the new text\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the text is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setText(final String text) {\r
+               checkWidget();\r
+               this.text = text;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/DownUpAppearTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/DownUpAppearTransition.java
new file mode 100644 (file)
index 0000000..56f8265
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * In this transition, the second control is behind, the first control is\r
+ * sliding from down to up\r
+ */\r
+public class DownUpAppearTransition extends VerticalTransition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.VerticalTransition#getCoeff()\r
+        */\r
+       @Override\r
+       protected int getCoeff() {\r
+               return -1;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.VerticalTransition#secondIsBehind()\r
+        */\r
+       @Override\r
+       protected boolean secondIsBehind() {\r
+               return false;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/DownUpTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/DownUpTransition.java
new file mode 100644 (file)
index 0000000..2844d82
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * In this transition, both control are sliding (vertical movement, down to up)\r
+ */\r
+public class DownUpTransition extends VerticalTransition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.VerticalTransition#getCoeff()\r
+        */\r
+       @Override\r
+       protected int getCoeff() {\r
+               return -1;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.VerticalTransition#secondIsBehind()\r
+        */\r
+       @Override\r
+       protected boolean secondIsBehind() {\r
+               return true;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/HorizontalTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/HorizontalTransition.java
new file mode 100644 (file)
index 0000000..a68403d
--- /dev/null
@@ -0,0 +1,86 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+import org.eclipse.swt.widgets.Control;\r
+\r
+/**\r
+ * Instances of this class are horizontal transitions (right>left,\r
+ * left>right...)\r
+ */\r
+public abstract class HorizontalTransition implements Transition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.Transition#performTransition(org.eclipse.swt.widgets.Control,\r
+        *      org.eclipse.swt.widgets.Control)\r
+        */\r
+       @Override\r
+       public void performTransition(final Control first, final Control second) {\r
+               if (first.isDisposed() || second.isDisposed()) {\r
+                       return;\r
+               }\r
+\r
+               final int[] currentPosition = new int[1];\r
+               currentPosition[0] = 0;\r
+               final int maxValue = first.getParent().getClientArea().width;\r
+\r
+               first.setBounds(0, 0, first.getBounds().width, first.getBounds().height);\r
+               second.setBounds(0, -1 * second.getBounds().width, second.getBounds().width, second.getBounds().height);\r
+\r
+               first.moveAbove(second);\r
+               second.setVisible(true);\r
+\r
+               if (first.isDisposed() || first.getDisplay().isDisposed()) {\r
+                       return;\r
+               }\r
+               first.getDisplay().timerExec(0, new Runnable() {\r
+\r
+                       @Override\r
+                       public void run() {\r
+\r
+                               if (first.isDisposed() || second.isDisposed()) {\r
+                                       return;\r
+                               }\r
+\r
+                               currentPosition[0] = currentPosition[0] + 10;\r
+                               if (currentPosition[0] > maxValue) {\r
+                                       first.setVisible(false);\r
+                                       second.setVisible(true);\r
+                                       second.setBounds(0, 0, first.getBounds().width, first.getBounds().height);\r
+                                       return;\r
+                               }\r
+\r
+                               first.setBounds(getCoeff() * currentPosition[0], 0, first.getBounds().width, first.getBounds().height);\r
+\r
+                               if (secondIsBehind()) {\r
+                                       second.setBounds(-1 * getCoeff() * (maxValue - currentPosition[0]), 0, second.getBounds().width, second.getBounds().height);\r
+                               }\r
+\r
+                               if (!first.isDisposed() && !first.getDisplay().isDisposed()) {\r
+                                       first.getDisplay().timerExec(10, this);\r
+                               }\r
+                       }\r
+\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * @return the multiplicator coefficient\r
+        */\r
+       protected abstract int getCoeff();\r
+\r
+       /**\r
+        * @return <code>true</code> if the second composite is behind the first\r
+        *         one, <code>false</code> otherwise\r
+        */\r
+       protected abstract boolean secondIsBehind();\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/LeftRightAppearTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/LeftRightAppearTransition.java
new file mode 100644 (file)
index 0000000..55239df
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * In this transition, the second control is behind, the first control is\r
+ * sliding from left to right\r
+ */\r
+public class LeftRightAppearTransition extends HorizontalTransition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.HorizontalTransition#getCoeff()\r
+        */\r
+       @Override\r
+       protected int getCoeff() {\r
+               return 1;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.HorizontalTransition#secondIsBehind()\r
+        */\r
+       @Override\r
+       protected boolean secondIsBehind() {\r
+               return false;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/LeftRightTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/LeftRightTransition.java
new file mode 100644 (file)
index 0000000..a7df752
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * In this transition, both control are sliding (vertical movement, left to\r
+ * right)\r
+ */\r
+public class LeftRightTransition extends HorizontalTransition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.HorizontalTransition#getCoeff()\r
+        */\r
+       @Override\r
+       protected int getCoeff() {\r
+               return 1;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.HorizontalTransition#secondIsBehind()\r
+        */\r
+       @Override\r
+       protected boolean secondIsBehind() {\r
+               return true;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/NoTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/NoTransition.java
new file mode 100644 (file)
index 0000000..cbdee8e
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+import org.eclipse.swt.widgets.Control;\r
+\r
+/**\r
+ * This transition is simple, because there is no effect :)\r
+ * \r
+ */\r
+class NoTransition implements Transition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.Transition#performTransition(org.eclipse.swt.widgets.Control,\r
+        *      org.eclipse.swt.widgets.Control)\r
+        */\r
+       @Override\r
+       public void performTransition(final Control first, final Control second) {\r
+               first.setVisible(false);\r
+               second.setVisible(true);\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/RightLeftAppearTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/RightLeftAppearTransition.java
new file mode 100644 (file)
index 0000000..94a38bb
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * In this transition, the second control is behind, the first control is\r
+ * sliding from right to left\r
+ */\r
+public class RightLeftAppearTransition extends HorizontalTransition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.HorizontalTransition#getCoeff()\r
+        */\r
+       @Override\r
+       protected int getCoeff() {\r
+               return -1;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.HorizontalTransition#secondIsBehind()\r
+        */\r
+       @Override\r
+       protected boolean secondIsBehind() {\r
+               return false;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/RightLeftTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/RightLeftTransition.java
new file mode 100644 (file)
index 0000000..cf3c803
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * In this transition, both control are sliding (vertical movement, right to\r
+ * left)\r
+ */\r
+public class RightLeftTransition extends HorizontalTransition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.HorizontalTransition#getCoeff()\r
+        */\r
+       @Override\r
+       protected int getCoeff() {\r
+               return -1;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.HorizontalTransition#secondIsBehind()\r
+        */\r
+       @Override\r
+       protected boolean secondIsBehind() {\r
+               return true;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TRANSITIONS.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TRANSITIONS.java
new file mode 100644 (file)
index 0000000..0a77856
--- /dev/null
@@ -0,0 +1,18 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * This enumeration is a list of transitions\r
+ */\r
+public enum TRANSITIONS {\r
+       LEFT_TO_RIGHT, LEFT_TO_RIGHT_AND_APPEAR, RIGHT_TO_LEFT, RIGHT_TO_LEFT_AND_APPEAR, UP_TO_DOWN, UP_TO_DOWN_AND_APPEAR, DOWN_TO_UP, DOWN_TO_UP_AND_APPEAR, NONE\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/Transition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/Transition.java
new file mode 100644 (file)
index 0000000..2921698
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+import org.eclipse.swt.widgets.Control;\r
+\r
+/**\r
+ * This interface describes a transition\r
+ */\r
+interface Transition {\r
+\r
+       /**\r
+        * Performs a transition between 2 controls of a TransitionComposite\r
+        * \r
+        * @param first first control\r
+        * @param second second control\r
+        */\r
+       void performTransition(Control first, Control second);\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TransitionComposite.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TransitionComposite.java
new file mode 100644 (file)
index 0000000..93ac865
--- /dev/null
@@ -0,0 +1,274 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+\r
+/**\r
+ * Instances of this class provide a multi-part composite. You can perform\r
+ * transitions when you move from one part to another\r
+ * <p>\r
+ * <dl>\r
+ * <dt><b>Styles:</b></dt>\r
+ * <dd>BORDER</dd>\r
+ * <dt><b>Events:</b></dt>\r
+ * <dd>(none)</dd>\r
+ * </dl>\r
+ * </p>\r
+ */\r
+public class TransitionComposite extends Composite {\r
+\r
+       private final List<Control> controls;\r
+       private int selection = 0;\r
+       private TRANSITIONS transition = TRANSITIONS.NONE;\r
+\r
+       /**\r
+        * Constructs a new instance of this class given its parent and a style\r
+        * value describing its behavior and appearance.\r
+        * <p>\r
+        * The style value is either one of the style constants defined in class\r
+        * <code>SWT</code> which is applicable to instances of this class, or must\r
+        * be built by <em>bitwise OR</em>'ing together (that is, using the\r
+        * <code>int</code> "|" operator) two or more of those <code>SWT</code>\r
+        * style constants. The class description lists the style constants that are\r
+        * applicable to the class. Style bits are also inherited from superclasses.\r
+        * </p>\r
+        * \r
+        * @param parent a composite control which will be the parent of the new\r
+        *            instance (cannot be null)\r
+        * @param style the style of control to construct\r
+        * \r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the parent</li>\r
+        *                </ul>\r
+        * \r
+        */\r
+       public TransitionComposite(final Composite parent, final int style) {\r
+               super(parent, style);\r
+               this.controls = new ArrayList<Control>();\r
+\r
+               addListener(SWT.Resize, new Listener() {\r
+                       @Override\r
+                       public void handleEvent(final Event e) {\r
+                               TransitionComposite.this.controls.get(TransitionComposite.this.selection).setBounds(getClientArea());\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Add a control to this composite\r
+        * \r
+        * @param control control to add\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void addControl(final Control control) {\r
+               checkWidget();\r
+               this.controls.add(control);\r
+               if (this.controls.size() == 1) {\r
+                       control.setVisible(true);\r
+               } else {\r
+                       control.setVisible(false);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)\r
+        */\r
+       @Override\r
+       public Point computeSize(final int wHint, final int hHint, final boolean changed) {\r
+               int width = 0, height = 0;\r
+               for (final Control control : this.controls) {\r
+                       final Point point = control.computeSize(wHint, hHint, changed);\r
+                       width = Math.max(width, point.x);\r
+                       height = Math.max(height, point.y);\r
+               }\r
+               return new Point(Math.max(width, wHint), Math.max(height, hHint));\r
+       }\r
+\r
+       /**\r
+        * @return the current transition\r
+        * @exception IllegalArgumentException <ul>\r
+        *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>\r
+        *                </ul>\r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public TRANSITIONS getTransition() {\r
+               checkWidget();\r
+               return this.transition;\r
+       }\r
+\r
+       /**\r
+        * Move selection to the first control\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void moveToFirst() {\r
+               checkWidget();\r
+               changeSelectionTo(0);\r
+       }\r
+\r
+       /**\r
+        * Move selection to the last control\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void moveToLast() {\r
+               checkWidget();\r
+               changeSelectionTo(this.controls.size() - 1);\r
+       }\r
+\r
+       /**\r
+        * Move selection to the next control\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void moveToNext() {\r
+               checkWidget();\r
+               final int index = this.selection + 1;\r
+               if (index == this.controls.size()) {\r
+                       return;\r
+               }\r
+               changeSelectionTo(index);\r
+       }\r
+\r
+       /**\r
+        * Move selection to the previous control\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void moveToPrevious() {\r
+               checkWidget();\r
+               final int index = this.selection - 1;\r
+               if (index < 0) {\r
+                       return;\r
+               }\r
+               changeSelectionTo(index);\r
+       }\r
+\r
+       /**\r
+        * Move selection to a given index\r
+        * \r
+        * @param index index of the new selection\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setSelection(final int index) {\r
+               checkWidget();\r
+               if (index < 0 || index > this.controls.size() - 1) {\r
+                       return;\r
+               }\r
+               changeSelectionTo(index);\r
+       }\r
+\r
+       /**\r
+        * Change current selection\r
+        * \r
+        * @param index index of the new selection\r
+        */\r
+       private void changeSelectionTo(final int index) {\r
+\r
+               final Transition t = TransitionFactory.getTransitionFor(this.transition);\r
+               t.performTransition(this.controls.get(this.selection), this.controls.get(index));\r
+\r
+               this.selection = index;\r
+               this.controls.get(this.selection).setBounds(getClientArea());\r
+       }\r
+\r
+       /**\r
+        * Move selection to a given control\r
+        * \r
+        * @param control control newly selected\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+       public void setSelection(final Control control) {\r
+               checkWidget();\r
+               for (int i = 0; i < this.controls.size(); i++) {\r
+                       if (this.controls.get(i) != null && this.controls.get(i).equals(control)) {\r
+                               changeSelectionTo(i);\r
+                               return;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Move selection to the first control\r
+        * \r
+        * @param transition new transition\r
+        * \r
+        * @exception SWTException <ul>\r
+        *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been\r
+        *                disposed</li>\r
+        *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the\r
+        *                thread that created the receiver</li>\r
+        *                </ul>\r
+        */\r
+\r
+       public void setTransition(final TRANSITIONS transition) {\r
+               checkWidget();\r
+               this.transition = transition;\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TransitionFactory.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/TransitionFactory.java
new file mode 100755 (executable)
index 0000000..ef73b8b
--- /dev/null
@@ -0,0 +1,48 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * This class is a transition factory\r
+ */\r
+public class TransitionFactory {\r
+\r
+       /**\r
+        * @param transition transition to get\r
+        * @return a transition corresponding to the <code>transition</code>\r
+        *         parameter\r
+        */\r
+       public static Transition getTransitionFor(final TRANSITIONS transition) {\r
+               switch (transition) {\r
+               case DOWN_TO_UP:\r
+                       return new DownUpTransition();\r
+               case DOWN_TO_UP_AND_APPEAR:\r
+                       return new DownUpAppearTransition();\r
+               case LEFT_TO_RIGHT:\r
+                       return new LeftRightTransition();\r
+               case LEFT_TO_RIGHT_AND_APPEAR:\r
+                       return new LeftRightAppearTransition();\r
+               case NONE:\r
+                       return new NoTransition();\r
+               case RIGHT_TO_LEFT:\r
+                       return new RightLeftTransition();\r
+               case RIGHT_TO_LEFT_AND_APPEAR:\r
+                       return new RightLeftAppearTransition();\r
+               case UP_TO_DOWN:\r
+                       return new UpDownTransition();\r
+               case UP_TO_DOWN_AND_APPEAR:\r
+                       return new UpDownAppearTransition();\r
+        default:\r
+            return null;\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/UpDownAppearTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/UpDownAppearTransition.java
new file mode 100644 (file)
index 0000000..b849657
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * In this transition, the second control is behind, the first control is\r
+ * sliding from up to down\r
+ */\r
+public class UpDownAppearTransition extends VerticalTransition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.VerticalTransition#getCoeff()\r
+        */\r
+       @Override\r
+       protected int getCoeff() {\r
+               return 1;\r
+       }\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.VerticalTransition#secondIsBehind()\r
+        */\r
+       @Override\r
+       protected boolean secondIsBehind() {\r
+               return false;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/UpDownTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/UpDownTransition.java
new file mode 100644 (file)
index 0000000..e352a59
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+/**\r
+ * In this transition, both control are sliding (vertical movement, up to down)\r
+ */\r
+public class UpDownTransition extends VerticalTransition {\r
+\r
+       @Override\r
+       protected int getCoeff() {\r
+               return 1;\r
+       }\r
+\r
+       @Override\r
+       protected boolean secondIsBehind() {\r
+               return true;\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/VerticalTransition.java b/org.tizen.common.externals/src/org/mihalis/opal/transitionComposite/VerticalTransition.java
new file mode 100644 (file)
index 0000000..ffe0942
--- /dev/null
@@ -0,0 +1,84 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron@gmail.com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.transitionComposite;\r
+\r
+import org.eclipse.swt.widgets.Control;\r
+\r
+/**\r
+ * Instances of this class are vertical transitions (down>up, up>down...)\r
+ */\r
+abstract class VerticalTransition implements Transition {\r
+\r
+       /**\r
+        * @see org.mihalis.opal.transitionComposite.Transition#performTransition(org.eclipse.swt.widgets.Control,\r
+        *      org.eclipse.swt.widgets.Control)\r
+        */\r
+       @Override\r
+       public void performTransition(final Control first, final Control second) {\r
+               if (first.isDisposed() || second.isDisposed()) {\r
+                       return;\r
+               }\r
+\r
+               final int[] currentPosition = new int[1];\r
+               currentPosition[0] = 0;\r
+               final int maxValue = first.getParent().getClientArea().height;\r
+\r
+               first.setBounds(0, 0, first.getBounds().width, first.getBounds().height);\r
+               second.setBounds(0, -1 * second.getBounds().width, second.getBounds().width, second.getBounds().height);\r
+\r
+               first.moveAbove(second);\r
+               second.setVisible(true);\r
+\r
+               if (first.isDisposed() || first.getDisplay().isDisposed()) {\r
+                       return;\r
+               }\r
+\r
+               first.getDisplay().timerExec(0, new Runnable() {\r
+\r
+                       @Override\r
+                       public void run() {\r
+\r
+                               if (first.isDisposed() || second.isDisposed()) {\r
+                                       return;\r
+                               }\r
+\r
+                               currentPosition[0] = currentPosition[0] + 10;\r
+                               if (currentPosition[0] > maxValue) {\r
+                                       first.setVisible(false);\r
+                                       second.setBounds(0, 0, first.getBounds().width, first.getBounds().height);\r
+\r
+                                       return;\r
+                               }\r
+\r
+                               first.setBounds(0, getCoeff() * currentPosition[0], first.getBounds().width, first.getBounds().height);\r
+                               if (secondIsBehind()) {\r
+                                       second.setBounds(0, -1 * getCoeff() * (maxValue - currentPosition[0]), second.getBounds().width, second.getBounds().height);\r
+                               }\r
+                               if (!first.isDisposed() && !first.getDisplay().isDisposed()) {\r
+                                       first.getDisplay().timerExec(15, this);\r
+                               }\r
+                       }\r
+\r
+               });\r
+\r
+       }\r
+\r
+       /**\r
+        * @return the multiplicator coefficient\r
+        */\r
+       protected abstract int getCoeff();\r
+\r
+       /**\r
+        * @return <code>true</code> if the second composite is behind the first\r
+        *         one, <code>false</code> otherwise\r
+        */\r
+       protected abstract boolean secondIsBehind();\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/utils/FileToolbox.java b/org.tizen.common.externals/src/org/mihalis/opal/utils/FileToolbox.java
new file mode 100644 (file)
index 0000000..7201ffc
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation\r
+ *******************************************************************************/\r
+package org.mihalis.opal.utils;\r
+\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+\r
+public class FileToolbox {\r
+\r
+    /**\r
+     * Loads a file into a stream\r
+     * \r
+     * @param fileName file name\r
+     * @return a stream composed of this file\r
+     */\r
+    public static InputStream getInputStream(final String fileName) {\r
+        if (fileName.startsWith("jar:")) {\r
+            URL url;\r
+            try {\r
+                url = new URL(fileName);\r
+                return url.openStream();\r
+            } catch (final MalformedURLException e) {\r
+                throw new RuntimeException(e);\r
+            } catch (final IOException e) {\r
+                throw new RuntimeException(e);\r
+            }\r
+        } else {\r
+            try {\r
+                return new FileInputStream(fileName);\r
+            } catch (final FileNotFoundException e) {\r
+                throw new RuntimeException(e);\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/utils/HTMLStyledTextParser.java b/org.tizen.common.externals/src/org/mihalis/opal/utils/HTMLStyledTextParser.java
new file mode 100644 (file)
index 0000000..d928047
--- /dev/null
@@ -0,0 +1,179 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.utils;\r
+\r
+import java.io.IOException;\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import javax.swing.text.MutableAttributeSet;\r
+import javax.swing.text.html.HTML.Tag;\r
+import javax.swing.text.html.HTMLEditorKit;\r
+import javax.swing.text.html.HTMLEditorKit.ParserCallback;\r
+import javax.swing.text.html.parser.ParserDelegator;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyleRange;\r
+import org.eclipse.swt.custom.StyledText;\r
+\r
+/**\r
+ * Instances of this class are used to convert HTML content of a styled text\r
+ * into style ranges\r
+ */\r
+public class HTMLStyledTextParser extends ParserCallback {\r
+\r
+       private final List<StyleRange> listOfStyles;\r
+       private final StyledText styledText;\r
+       private int position;\r
+       private final StringBuilder outputString;\r
+\r
+       private StyleRange currentStyleRange;\r
+       private TagType currentTagType;\r
+       private int currentPosition;\r
+\r
+       private enum TagType {\r
+               B, U, I\r
+       };\r
+\r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param styledText styled text to analyze\r
+        */\r
+       HTMLStyledTextParser(final StyledText styledText) {\r
+               super();\r
+               this.styledText = styledText;\r
+               this.position = -1;\r
+               this.listOfStyles = new ArrayList<StyleRange>();\r
+               this.currentStyleRange = null;\r
+               this.currentTagType = null;\r
+               this.currentPosition = 0;\r
+               this.outputString = new StringBuilder();\r
+       }\r
+\r
+       /**\r
+        * @see javax.swing.text.html.HTMLEditorKit.ParserCallback#handleStartTag(javax.swing.text.html.HTML.Tag,\r
+        *      javax.swing.text.MutableAttributeSet, int)\r
+        */\r
+       @Override\r
+       public void handleStartTag(final Tag t, final MutableAttributeSet a, final int pos) {\r
+               if (t == Tag.B) {\r
+                       this.currentStyleRange = new StyleRange();\r
+                       this.currentTagType = TagType.B;\r
+                       this.currentPosition = this.position;\r
+               }\r
+               if (t == Tag.I) {\r
+                       this.currentStyleRange = new StyleRange();\r
+                       this.currentTagType = TagType.I;\r
+                       this.currentPosition = this.position;\r
+               }\r
+               if (t == Tag.U) {\r
+                       this.currentStyleRange = new StyleRange();\r
+                       this.currentTagType = TagType.U;\r
+                       this.currentPosition = this.position;\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * @see javax.swing.text.html.HTMLEditorKit.ParserCallback#handleEndTag(javax.swing.text.html.HTML.Tag,\r
+        *      int)\r
+        */\r
+       @Override\r
+       public void handleEndTag(final Tag t, final int pos) {\r
+\r
+               if (t != Tag.B && t != Tag.I && t != Tag.U) {\r
+                       return;\r
+               }\r
+\r
+               int style;\r
+               boolean underline;\r
+               if (t == Tag.B) {\r
+                       if (TagType.B != this.currentTagType) {\r
+                               throw new RuntimeException("Error parsing [" + this.styledText.getText() + "] : bad syntax");\r
+                       }\r
+                       style = SWT.BOLD;\r
+                       underline = false;\r
+               } else if (t == Tag.I) {\r
+                       if (TagType.I != this.currentTagType) {\r
+                               throw new RuntimeException("Error parsing [" + this.styledText.getText() + "] : bad syntax");\r
+                       }\r
+                       style = SWT.ITALIC;\r
+                       underline = false;\r
+               } else if (t == Tag.U) {\r
+                       if (TagType.U != this.currentTagType) {\r
+                               throw new RuntimeException("Error parsing [" + this.styledText.getText() + "] : bad syntax");\r
+                       }\r
+                       style = SWT.NORMAL;\r
+                       underline = true;\r
+               } else {\r
+                       style = SWT.NORMAL;\r
+                       underline = false;\r
+               }\r
+\r
+               this.currentStyleRange.start = this.currentPosition;\r
+               this.currentStyleRange.length = this.position - this.currentPosition + 1;\r
+               this.currentStyleRange.fontStyle = style;\r
+               this.currentStyleRange.underline = underline;\r
+               this.listOfStyles.add(this.currentStyleRange);\r
+\r
+               this.currentStyleRange = null;\r
+               this.currentTagType = null;\r
+       }\r
+\r
+       /**\r
+        * @see javax.swing.text.html.HTMLEditorKit.ParserCallback#handleError(java.lang.String,\r
+        *      int)\r
+        */\r
+       @Override\r
+       public void handleError(final String errorMsg, final int pos) {\r
+               throw new RuntimeException("Parsing error: " + errorMsg + " at " + pos);\r
+       }\r
+\r
+       /**\r
+        * @see javax.swing.text.html.HTMLEditorKit.ParserCallback#handleText(char[],\r
+        *      int)\r
+        */\r
+       @Override\r
+       public void handleText(final char[] data, final int pos) {\r
+               this.outputString.append(data);\r
+               this.position += data.length;\r
+       }\r
+\r
+       /**\r
+        * @see javax.swing.text.html.HTMLEditorKit.ParserCallback#handleSimpleTag(javax.swing.text.html.HTML.Tag,\r
+        *      javax.swing.text.MutableAttributeSet, int)\r
+        */\r
+       @Override\r
+       public void handleSimpleTag(final Tag t, final MutableAttributeSet a, final int pos) {\r
+               if (t == Tag.BR) {\r
+                       this.outputString.append("\n");\r
+                       this.position += t.toString().length();\r
+\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Parse the content, build the list of style ranges and apply them to the\r
+        * styled text widget\r
+        * \r
+        * @throws IOException\r
+        */\r
+       public void parse() throws IOException {\r
+               final HTMLEditorKit.Parser parser = new ParserDelegator();\r
+               parser.parse(new StringReader(this.styledText.getText()), this, true);\r
+               this.styledText.setText(this.outputString.toString());\r
+               this.styledText.setStyleRanges(this.listOfStyles.toArray(new StyleRange[this.listOfStyles.size()]));\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/utils/ResourceManager.java b/org.tizen.common.externals/src/org/mihalis/opal/utils/ResourceManager.java
new file mode 100644 (file)
index 0000000..da60f64
--- /dev/null
@@ -0,0 +1,56 @@
+package org.mihalis.opal.utils;\r
+\r
+import java.util.ResourceBundle;\r
+\r
+public class ResourceManager {\r
+       private static final ResourceBundle RSC = ResourceBundle.getBundle("resources/opal");\r
+\r
+       public static final String OK = "Ok";\r
+       public static final String CANCEL = "Cancel";\r
+       public static final String CLOSE = "Close";\r
+       public static final String YES = "Yes";\r
+       public static final String NO = "No";\r
+\r
+       public static final String MEGABYTES = "megabytes";\r
+       public static final String PERFORM_GC = "performGC";\r
+\r
+       public static final String LOGIN = "login";\r
+       public static final String NAME = "name";\r
+       public static final String PASSWORD = "password";\r
+       public static final String REMEMBER_PASSWORD = "rememberPassword";\r
+       public static final String LOGIN_FAILED = "loginFailed";\r
+\r
+       public static final String INPUT = "Input";\r
+       public static final String APPLICATION_ERROR = "ApplicationError";\r
+       public static final String INFORMATION = "Information";\r
+       public static final String WARNING = "Warning";\r
+       public static final String CHOICE = "Choice";\r
+       public static final String EXCEPTION = "Exception";\r
+       public static final String SELECT = "Select";\r
+       public static final String FEWER_DETAILS = "FewerDetails";\r
+       public static final String MORE_DETAILS = "MoreDetails";\r
+\r
+       public static final String TIP_OF_THE_DAY = "tipOfTheDay";\r
+       public static final String DID_YOU_KNOW = "didYouKnow";\r
+       public static final String SHOW_TIP_AT_STARTUP = "showTipAtStartup";\r
+       public static final String PREVIOUS_TIP = "previousTip";\r
+       public static final String NEXT_TIP = "nextTip";\r
+\r
+       public static final String CHOOSE = "choose";\r
+       public static final String PREFERENCES = "preferences";\r
+       public static final String VALID_URL = "validURL";\r
+       public static final String CHOOSE_DIRECTORY = "chooseDirectory";\r
+       public static final String ITALIC = "italic";\r
+       public static final String BOLD = "bold";\r
+\r
+       /**\r
+        * Get a translated label\r
+        * \r
+        * @param key key to get\r
+        * @return the translated value of the key\r
+        */\r
+       public static String getLabel(final String key) {\r
+               return RSC.getString(key);\r
+       }\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/utils/SWTGraphicUtil.java b/org.tizen.common.externals/src/org/mihalis/opal/utils/SWTGraphicUtil.java
new file mode 100644 (file)
index 0000000..e28dd52
--- /dev/null
@@ -0,0 +1,463 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.utils;\r
+\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.ImageData;\r
+import org.eclipse.swt.graphics.PaletteData;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.graphics.Resource;\r
+import org.eclipse.swt.graphics.Transform;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Monitor;\r
+import org.eclipse.swt.widgets.Shell;\r
+\r
+/**\r
+ * This class is a singleton that provides useful methods\r
+ */\r
+public class SWTGraphicUtil {\r
+\r
+       /**\r
+        * Constructor\r
+        */\r
+       private SWTGraphicUtil() {\r
+       }\r
+\r
+       /**\r
+        * Dispose safely any SWT resource when a control is disposed\r
+        * \r
+        * @param r the resource to dispose\r
+        */\r
+       public static void dispose(final Control control, final Resource r) {\r
+               control.addDisposeListener(new DisposeListener() {\r
+\r
+                       @Override\r
+                       public void widgetDisposed(final DisposeEvent e) {\r
+                               dispose(r);\r
+                       }\r
+               });\r
+       }\r
+\r
+       /**\r
+        * Dispose safely any SWT resource\r
+        * \r
+        * @param r the resource to dispose\r
+        */\r
+       public static void dispose(final Resource r) {\r
+               if (r != null && !r.isDisposed()) {\r
+                       r.dispose();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Loads an image and create a SWT Image corresponding to this file\r
+        * \r
+        * @param fileName file name of the image\r
+        * @return an image\r
+        * @see org.eclipse.swt.graphics.Image\r
+        */\r
+       public static Image createImage(final String fileName) {\r
+               return new Image(Display.getCurrent(), SWTGraphicUtil.class.getClassLoader().getResourceAsStream(fileName));\r
+       }\r
+\r
+       /**\r
+        * Create a reflected image of a source Inspired by Daniel Spiewak\r
+        * (http://www.eclipsezone.com/eclipse/forums/t91013.html)\r
+        * \r
+        * @param source source to be reflected\r
+        * @return the source image with a reflection\r
+        */\r
+       public static Image createReflectedImage(final Image source) {\r
+               if (source == null) {\r
+                       return null;\r
+               }\r
+\r
+               if (source.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               // Create a new image\r
+               final Rectangle sourceBounds = source.getBounds();\r
+               final Image newImage = new Image(source.getDevice(), new Rectangle(0, 0, sourceBounds.width, (int) (sourceBounds.height * 1.5)));\r
+               final GC gc = new GC(newImage);\r
+               gc.setAdvanced(true);\r
+\r
+               gc.drawImage(source, 0, 0);\r
+\r
+               // Add the reflection\r
+               final Transform t = new Transform(source.getDevice());\r
+               t.setElements(1, 0, 0, -.5f, 0, sourceBounds.height + sourceBounds.height / 2);\r
+               gc.setTransform(t);\r
+\r
+               gc.drawImage(source, 0, 0);\r
+\r
+               t.dispose();\r
+               gc.dispose();\r
+\r
+               // And add the alpha mask\r
+               final ImageData imgData = newImage.getImageData();\r
+               final int width = imgData.width;\r
+               final int height = imgData.height;\r
+               final byte[] alphaData = new byte[height * width];\r
+\r
+               final byte[] noAlpha = new byte[width];\r
+               for (int x = 0; x < width; x++) {\r
+                       noAlpha[x] = (byte) 255;\r
+               }\r
+\r
+               for (int y = 0; y < height; y++) {\r
+                       final byte[] alphaRow = new byte[width];\r
+                       if (y < sourceBounds.height) {\r
+                               System.arraycopy(noAlpha, 0, alphaData, y * width, width);\r
+                       } else {\r
+                               for (int x = 0; x < width; x++) {\r
+                                       alphaRow[x] = (byte) (255 - 255 * y / height);\r
+                               }\r
+                               System.arraycopy(alphaRow, 0, alphaData, y * width, width);\r
+                       }\r
+\r
+               }\r
+               imgData.alphaData = alphaData;\r
+               return new Image(source.getDevice(), imgData);\r
+       }\r
+\r
+       /**\r
+        * Returns a new scaled image.\r
+        * \r
+        * @param source the image to be scaled\r
+        * @param newWidth new width of the image\r
+        * @param newHeight new height of the image\r
+        * @return a scaled image of the source\r
+        */\r
+       public static Image resize(final Image source, final int newWidth, final int newHeight) {\r
+\r
+               if (source == null) {\r
+                       return null;\r
+               }\r
+\r
+               if (source.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               final Image scaledImage = new Image(source.getDevice(), newWidth, newHeight);\r
+               final GC gc = new GC(scaledImage);\r
+               gc.setAntialias(SWT.ON);\r
+               gc.setInterpolation(SWT.HIGH);\r
+               gc.drawImage(source, 0, 0, source.getBounds().width, source.getBounds().height, 0, 0, newWidth, newHeight);\r
+               gc.dispose();\r
+\r
+               return scaledImage;\r
+       }\r
+\r
+       /**\r
+        * Create a reflected and resized version of an image\r
+        * \r
+        * @param source source image to be scaled and reflected\r
+        * @param newWidth new width of the scaled image\r
+        * @param newHeight new height of the scaled image\r
+        * @return the resized and reflected image\r
+        */\r
+       public static Image createReflectedResizedImage(final Image source, final int newWidth, final int newHeight) {\r
+               if (source == null) {\r
+                       return null;\r
+               }\r
+\r
+               if (source.isDisposed()) {\r
+                       SWT.error(SWT.ERROR_WIDGET_DISPOSED);\r
+               }\r
+\r
+               final Image newImage = new Image(source.getDevice(), newWidth, (int) (newHeight * 1.5));\r
+               final GC gc = new GC(newImage);\r
+               gc.setAntialias(SWT.ON);\r
+               gc.setInterpolation(SWT.HIGH);\r
+               gc.drawImage(source, 0, 0, source.getBounds().width, source.getBounds().height, 0, 0, newWidth, newHeight);\r
+\r
+               // Add the reflection\r
+               final Transform t = new Transform(source.getDevice());\r
+               t.setElements(1, 0, 0, -.5f, 0, (float) (newHeight * 1.5));\r
+               gc.setTransform(t);\r
+\r
+               gc.drawImage(source, 0, 0, source.getBounds().width, source.getBounds().height, 0, 0, newWidth, newHeight);\r
+\r
+               t.dispose();\r
+               gc.dispose();\r
+\r
+               // And add the alpha mask\r
+               final ImageData imgData = newImage.getImageData();\r
+               final int width = imgData.width;\r
+               final int height = imgData.height;\r
+               final byte[] alphaData = new byte[height * width];\r
+\r
+               final byte[] noAlpha = new byte[width];\r
+               for (int x = 0; x < width; x++) {\r
+                       noAlpha[x] = (byte) 255;\r
+               }\r
+\r
+               for (int y = 0; y < height; y++) {\r
+                       final byte[] alphaRow = new byte[width];\r
+                       if (y < newHeight) {\r
+                               System.arraycopy(noAlpha, 0, alphaData, y * width, width);\r
+                       } else {\r
+                               for (int x = 0; x < width; x++) {\r
+                                       alphaRow[x] = (byte) (255 - 255 * y / height);\r
+                               }\r
+                               System.arraycopy(alphaRow, 0, alphaData, y * width, width);\r
+                       }\r
+\r
+               }\r
+               imgData.alphaData = alphaData;\r
+               return new Image(source.getDevice(), imgData);\r
+\r
+       }\r
+\r
+       /**\r
+        * Center a shell on the screen\r
+        * \r
+        * @param shell shell to center\r
+        */\r
+       public static void centerShell(final Shell shell) {\r
+               final Monitor primary = shell.getDisplay().getPrimaryMonitor();\r
+               final Rectangle bounds = primary.getBounds();\r
+               final Rectangle rect = shell.getBounds();\r
+               final int x = bounds.x + (bounds.width - rect.width) / 2;\r
+               final int y = bounds.y + (bounds.height - rect.height) / 2;\r
+               shell.setLocation(x, y);\r
+       }\r
+\r
+       /**\r
+        * Apply a very basic HTML formating to a text stored in a StyledText\r
+        * widget. Supported tags are <B>, <I> and <U>\r
+        * \r
+        * @param styledText styled text that contains an HTML text\r
+        */\r
+       public static void applyHTMLFormating(final StyledText styledText) {\r
+               try {\r
+                       new HTMLStyledTextParser(styledText).parse();\r
+               } catch (final IOException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @param originalImageData The ImageData to be average blurred.\r
+        *            Transparency information will be ignored.\r
+        * @param radius the number of radius pixels to consider when blurring\r
+        *            image.\r
+        * @return A blurred copy of the image data, or null if an error occured.\r
+        * @author Nicholas Rajendram\r
+        * @see http://www.jasonwaltman.com/thesis/filter-blur.html\r
+        * @see http://www.blackpawn.com/texts/blur/default.html\r
+        */\r
+       public static ImageData blur(final ImageData originalImageData, int radius) {\r
+               /*\r
+                * This method will vertically blur all the pixels in a row at once.\r
+                * This blurring is performed incrementally to each row.\r
+                * \r
+                * In order to vertically blur any given pixel, maximally (radius * 2 +\r
+                * 1) pixels must be examined. Since each of these pixels exists in the\r
+                * same column, they span across a series of consecutive rows. These\r
+                * rows are horizontally blurred before being cached and used as input\r
+                * for the vertical blur. Blurring a pixel horizontally and then\r
+                * vertically is equivalent to blurring the pixel with both its\r
+                * horizontal and vertical neighbours at once.\r
+                * \r
+                * Pixels are blurred under the notion of a 'summing scope'. A certain\r
+                * scope of pixels in a column are summed then averaged to determine a\r
+                * target pixel's resulting RGB value. When the next lower target pixel\r
+                * is being calculated, the topmost pixel is removed from the summing\r
+                * scope (by subtracting its RGB) and a new pixel is added to the bottom\r
+                * of the scope (by adding its RGB). In this sense, the summing scope is\r
+                * moving downward.\r
+                */\r
+               if (radius < 1) {\r
+                       return originalImageData;\r
+               }\r
+               // prepare new image data with 24-bit direct palette to hold blurred\r
+               // copy of image\r
+               final ImageData newImageData = new ImageData(originalImageData.width, originalImageData.height, 24, new PaletteData(0xFF, 0xFF00, 0xFF0000));\r
+               if (radius >= newImageData.height || radius >= newImageData.width) {\r
+                       radius = Math.min(newImageData.height, newImageData.width) - 1;\r
+               }\r
+               // initialize cache\r
+               final ArrayList<RGB[]> rowCache = new ArrayList<RGB[]>();\r
+               final int cacheSize = radius * 2 + 1 > newImageData.height ? newImageData.height : radius * 2 + 1; // number\r
+                                                                                                                                                                                                                       // of\r
+                                                                                                                                                                                                                       // rows\r
+                                                                                                                                                                                                                       // of\r
+                                                                                                                                                                                                                       // imageData\r
+                                                                                                                                                                                                                       // we\r
+                                                                                                                                                                                                                       // cache\r
+               int cacheStartIndex = 0; // which row of imageData the cache begins with\r
+               for (int row = 0; row < cacheSize; row++) {\r
+                       // row data is horizontally blurred before caching\r
+                       rowCache.add(rowCache.size(), blurRow(originalImageData, row, radius));\r
+               }\r
+               // sum red, green, and blue values separately for averaging\r
+               final RGB[] rowRGBSums = new RGB[newImageData.width];\r
+               final int[] rowRGBAverages = new int[newImageData.width];\r
+               int topSumBoundary = 0; // current top row of summed values scope\r
+               int targetRow = 0; // row with RGB averages to be determined\r
+               int bottomSumBoundary = 0; // current bottom row of summed values scope\r
+               int numRows = 0; // number of rows included in current summing scope\r
+               for (int i = 0; i < newImageData.width; i++) {\r
+                       rowRGBSums[i] = new RGB(0, 0, 0);\r
+               }\r
+               while (targetRow < newImageData.height) {\r
+                       if (bottomSumBoundary < newImageData.height) {\r
+                               do {\r
+                                       // sum pixel RGB values for each column in our radius scope\r
+                                       for (int col = 0; col < newImageData.width; col++) {\r
+                                               rowRGBSums[col].red += rowCache.get(bottomSumBoundary - cacheStartIndex)[col].red;\r
+                                               rowRGBSums[col].green += rowCache.get(bottomSumBoundary - cacheStartIndex)[col].green;\r
+                                               rowRGBSums[col].blue += rowCache.get(bottomSumBoundary - cacheStartIndex)[col].blue;\r
+                                       }\r
+                                       numRows++;\r
+                                       bottomSumBoundary++; // move bottom scope boundary lower\r
+                                       if (bottomSumBoundary < newImageData.height && bottomSumBoundary - cacheStartIndex > radius * 2) {\r
+                                               // grow cache\r
+                                               rowCache.add(rowCache.size(), blurRow(originalImageData, bottomSumBoundary, radius));\r
+                                       }\r
+                               } while (bottomSumBoundary <= radius); // to initialize\r
+                                                                                                               // rowRGBSums at start\r
+                       }\r
+                       if (targetRow - topSumBoundary > radius) {\r
+                               // subtract values of top row from sums as scope of summed\r
+                               // values moves down\r
+                               for (int col = 0; col < newImageData.width; col++) {\r
+                                       rowRGBSums[col].red -= rowCache.get(topSumBoundary - cacheStartIndex)[col].red;\r
+                                       rowRGBSums[col].green -= rowCache.get(topSumBoundary - cacheStartIndex)[col].green;\r
+                                       rowRGBSums[col].blue -= rowCache.get(topSumBoundary - cacheStartIndex)[col].blue;\r
+                               }\r
+                               numRows--;\r
+                               topSumBoundary++; // move top scope boundary lower\r
+                               rowCache.remove(0); // remove top row which is out of summing\r
+                                                                       // scope\r
+                               cacheStartIndex++;\r
+                       }\r
+                       // calculate each column's RGB-averaged pixel\r
+                       for (int col = 0; col < newImageData.width; col++) {\r
+                               rowRGBAverages[col] = newImageData.palette.getPixel(new RGB(rowRGBSums[col].red / numRows, rowRGBSums[col].green / numRows, rowRGBSums[col].blue / numRows));\r
+                       }\r
+                       // replace original pixels\r
+                       newImageData.setPixels(0, targetRow, newImageData.width, rowRGBAverages, 0);\r
+                       targetRow++;\r
+               }\r
+               return newImageData;\r
+       }\r
+\r
+       /**\r
+        * Average blurs a given row of image data. Returns the blurred row as a\r
+        * matrix of separated RGB values.\r
+        */\r
+       private static RGB[] blurRow(final ImageData originalImageData, final int row, final int radius) {\r
+               final RGB[] rowRGBAverages = new RGB[originalImageData.width]; // resulting\r
+                                                                                                                                               // rgb\r
+                                                                                                                                               // averages\r
+               final int[] lineData = new int[originalImageData.width];\r
+               originalImageData.getPixels(0, row, originalImageData.width, lineData, 0);\r
+               int r = 0, g = 0, b = 0; // sum red, green, and blue values separately\r
+                                                                       // for averaging\r
+               int leftSumBoundary = 0; // beginning index of summed values scope\r
+               int targetColumn = 0; // column of RGB average to be determined\r
+               int rightSumBoundary = 0; // ending index of summed values scope\r
+               int numCols = 0; // number of columns included in current summing scope\r
+               RGB rgb;\r
+               while (targetColumn < lineData.length) {\r
+                       if (rightSumBoundary < lineData.length) {\r
+                               // sum RGB values for each pixel in our radius scope\r
+                               do {\r
+                                       rgb = originalImageData.palette.getRGB(lineData[rightSumBoundary]);\r
+                                       r += rgb.red;\r
+                                       g += rgb.green;\r
+                                       b += rgb.blue;\r
+                                       numCols++;\r
+                                       rightSumBoundary++;\r
+                               } while (rightSumBoundary <= radius); // to initialize summing\r
+                                                                                                               // scope at start\r
+                       }\r
+                       // subtract sum of left pixel as summing scope moves right\r
+                       if (targetColumn - leftSumBoundary > radius) {\r
+                               rgb = originalImageData.palette.getRGB(lineData[leftSumBoundary]);\r
+                               r -= rgb.red;\r
+                               g -= rgb.green;\r
+                               b -= rgb.blue;\r
+                               numCols--;\r
+                               leftSumBoundary++;\r
+                       }\r
+                       // calculate RGB averages\r
+                       rowRGBAverages[targetColumn] = new RGB(r / numCols, g / numCols, b / numCols);\r
+                       targetColumn++;\r
+               }\r
+               return rowRGBAverages;\r
+       }\r
+\r
+       /**\r
+        * Enable/disable all widgets of a control\r
+        * \r
+        * @param control control to enable/disable\r
+        * @param enable <code>true</code> to enable, <code>false</code> to disable\r
+        */\r
+       public static void enable(final Control control, final boolean enable) {\r
+               if (control instanceof Composite) {\r
+                       for (final Control c : ((Composite) control).getChildren()) {\r
+                               enable(c, enable);\r
+                       }\r
+               }\r
+               control.setEnabled(enable);\r
+       }\r
+\r
+       /**\r
+        * Build a font from a given control. Useful if we just want a bold label\r
+        * for example\r
+        * \r
+        * @param control control that handle the default font\r
+        * @param style new style\r
+        * @return a font with the given style\r
+        */\r
+       public static Font buildFontFrom(final Control control, final int style) {\r
+               final Font temp = control.getFont();\r
+               final FontData[] fontData = temp.getFontData();\r
+               if (fontData == null || fontData.length == 0) {\r
+                       return temp;\r
+               }\r
+               return new Font(control.getDisplay(), fontData[0].getName(), fontData[0].getHeight(), style);\r
+       }\r
+\r
+       /**\r
+        * Build a font from a given control. Useful if we just want a bold label\r
+        * for example\r
+        * \r
+        * @param control control that handle the default font\r
+        * @param style new style\r
+        * @return a font with the given style\r
+        */\r
+       public static Font buildFontFrom(final Control control, final int style, final int size) {\r
+               final Font temp = control.getFont();\r
+               final FontData[] fontData = temp.getFontData();\r
+               if (fontData == null || fontData.length == 0) {\r
+                       return temp;\r
+               }\r
+               return new Font(control.getDisplay(), fontData[0].getName(), size, style);\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/utils/SimpleSelectionAdapter.java b/org.tizen.common.externals/src/org/mihalis/opal/utils/SimpleSelectionAdapter.java
new file mode 100644 (file)
index 0000000..1299df6
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.mihalis.opal.utils;\r
+\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+\r
+/**\r
+ * This class is an adapter for the SelectionListener. Both behaviours (DefaultSelected and Selected) are doing the same thing\r
+ */\r
+public abstract class SimpleSelectionAdapter implements SelectionListener {\r
+\r
+    /**\r
+     * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)\r
+     */\r
+    @Override\r
+    public void widgetDefaultSelected(final SelectionEvent e) {\r
+        this.handle(e);\r
+\r
+    }\r
+\r
+    /**\r
+     * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)\r
+     */\r
+    @Override\r
+    public void widgetSelected(final SelectionEvent e) {\r
+        this.handle(e);\r
+\r
+    }\r
+\r
+    /**\r
+     * Sent when selection occurs in the control.\r
+     * \r
+     * @param e - an event containing information about the selection\r
+     */\r
+    public abstract void handle(SelectionEvent e);\r
+\r
+}\r
diff --git a/org.tizen.common.externals/src/org/mihalis/opal/utils/StringUtil.java b/org.tizen.common.externals/src/org/mihalis/opal/utils/StringUtil.java
new file mode 100644 (file)
index 0000000..7c1994c
--- /dev/null
@@ -0,0 +1,73 @@
+/*******************************************************************************\r
+ * Copyright (c) 2011 Laurent CARON\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API\r
+ *******************************************************************************/\r
+package org.mihalis.opal.utils;\r
+\r
+import java.io.PrintWriter;\r
+import java.io.StringWriter;\r
+\r
+/**\r
+ * This class provides useful String manipulation methods\r
+ * \r
+ */\r
+public class StringUtil {\r
+       /**\r
+        * Check if a string is empty or null\r
+        * \r
+        * @param source source string\r
+        * @return <code>true</code> is the string is empty or null,\r
+        *         <code>false</code> otherwise\r
+        */\r
+       public static boolean isEmpty(final String source) {\r
+               return source == null || source.trim().isEmpty();\r
+       }\r
+\r
+       /**\r
+        * Converts exception stack trace as string\r
+        * \r
+        * @param exception exception to convert\r
+        * @return a string that contains the exception\r
+        */\r
+       public static final String stackStraceAsString(final Throwable exception) {\r
+               final StringWriter stringWriter = new StringWriter();\r
+               exception.printStackTrace(new PrintWriter(stringWriter));\r
+               return stringWriter.toString();\r
+       }\r
+\r
+       /**\r
+        * Insert a string in a middle of another string\r
+        * \r
+        * @param source source string\r
+        * @param newEntry string to insert into source\r
+        * @param position position to insert source\r
+        * @return the new string\r
+        */\r
+       public static String insertString(final String source, final String newEntry, final int position) {\r
+               final StringBuilder sb = new StringBuilder();\r
+               sb.append(source.substring(0, position)).append(newEntry).append(source.substring(position));\r
+               return sb.toString();\r
+       }\r
+\r
+       /**\r
+        * Remove a character in a String\r
+        * \r
+        * @param source source string\r
+        * @param position position of the character to remove\r
+        * @return the string without the character\r
+        */\r
+       public static String removeCharAt(final String source, final int position) {\r
+               final StringBuilder sb = new StringBuilder();\r
+               if (position == source.length()) {\r
+                       return source;\r
+               }\r
+               sb.append(source.substring(0, position)).append(source.substring(position + 1));\r
+               return sb.toString();\r
+       }\r
+}\r
diff --git a/org.tizen.common.externals/src/org/tizen/common/externals/ExternalsPlugin.java b/org.tizen.common.externals/src/org/tizen/common/externals/ExternalsPlugin.java
new file mode 100644 (file)
index 0000000..208ca6d
--- /dev/null
@@ -0,0 +1,50 @@
+package org.tizen.common.externals;\r
+\r
+import org.eclipse.ui.plugin.AbstractUIPlugin;\r
+import org.osgi.framework.BundleContext;\r
+\r
+/**\r
+ * The activator class controls the plug-in life cycle\r
+ */\r
+public class ExternalsPlugin extends AbstractUIPlugin {\r
+\r
+       // The plug-in ID\r
+       public static final String PLUGIN_ID = "org.tizen.common.extras"; //$NON-NLS-1$\r
+\r
+       // The shared instance\r
+       private static ExternalsPlugin plugin;\r
+       \r
+       /**\r
+        * The constructor\r
+        */\r
+       public ExternalsPlugin() {\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)\r
+        */\r
+       public void start(BundleContext context) throws Exception {\r
+               super.start(context);\r
+               plugin = this;\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)\r
+        */\r
+       public void stop(BundleContext context) throws Exception {\r
+               plugin = null;\r
+               super.stop(context);\r
+       }\r
+\r
+       /**\r
+        * Returns the shared instance\r
+        *\r
+        * @return the shared instance\r
+        */\r
+       public static ExternalsPlugin getDefault() {\r
+               return plugin;\r
+       }\r
+\r
+}\r
index bee14d1..a8b9447 100644 (file)
@@ -2,5 +2,4 @@ bin.includes = feature.xml,\
                license.html,\
                feature.properties,\
                epl-v10.html,\
-               LICENSE-2.0.htm
-root = rootfiles
+               LICENSE-2.0.htm
\ No newline at end of file
index 30796d6..71fb7d8 100644 (file)
@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<feature
-      id="org.tizen.common.feature"
-      label="Tizen Common Tools"
-      version="1.0.0.qualifier"
-      provider-name="Samsung"
-      plugin="org.tizen.base.platform"
-      license-feature="org.tizen.base.feature">
-
-   <description>
-      Common library for Tizen SDK.
-   </description>
-
-   <copyright>
-      Copyright (c) 2010-2011, Samsung Electronics Co., LTD. All rights reserved.
-   </copyright>
-
-   <license url="license.html">
+<?xml version="1.0" encoding="UTF-8"?>\r
+<feature\r
+      id="org.tizen.common.feature"\r
+      label="Tizen Common Tools"\r
+      version="1.0.0.qualifier"\r
+      provider-name="Tizen"\r
+      plugin="org.tizen.base.platform"\r
+      license-feature="org.tizen.base.feature">\r
+\r
+   <description>\r
+      Common library for Tizen SDK.\r
+   </description>\r
+\r
+   <copyright>\r
+      Copyright (c)\r
+   </copyright>\r
+\r
+   <license url="license.html">\r
       Tizen SDK
 
 Tizen SDK contains software portions licensed under various open source licenses as well as proprietary components.  All open source software portions (&quot;Open Source Software&quot;) are licensed under the open source licenses that accompany such Open Source Software.
@@ -26,18 +26,32 @@ Except for the Open Source Software contained in Tizen SDK, all other software p
 
 You may access and download Tizen SDK Open Source Software at: http://developer.tizen.org/download/tizenopensdk.tar.gz
 
-BY CLICKING THE &quot;I AGREE&quot; BUTTON OR BY USING ANY PART OF TIZEN SDK, YOU AGREE (ON BEHALF OF YOURSELF AND/OR YOUR COMPANY) TO THE OPEN SOURCE SOFTWARE LICENSE TERMS AND THE TIZEN SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT. IF YOU DO NOT AGREE WITH THE OPEN SOURCE SOFTWARE LICENSE TERMS OR THE TIZEN SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT, YOU MAY NOT DOWNLOAD OR USE TIZEN SDK.
-   </license>
-
-   <plugin
-         id="org.tizen.common"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
+BY CLICKING THE &quot;I AGREE&quot; BUTTON OR BY USING ANY PART OF TIZEN SDK, YOU AGREE (ON BEHALF OF YOURSELF AND/OR YOUR COMPANY) TO THE OPEN SOURCE SOFTWARE LICENSE TERMS AND THE TIZEN SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT. IF YOU DO NOT AGREE WITH THE OPEN SOURCE SOFTWARE LICENSE TERMS OR THE TIZEN SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT, YOU MAY NOT DOWNLOAD OR USE TIZEN SDK.\r
+   </license>\r
+\r
+   <plugin\r
+         id="org.tizen.common"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="org.tizen.common.connection"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="org.tizen.common.externals"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
 
    <plugin
-         id="org.tizen.common.connection"
+         id="org.tizen.common.verrari"
          download-size="0"
          install-size="0"
          version="0.0.0"
diff --git a/org.tizen.common.feature/rootfiles/resources/icons/tizen-sdk-ide.ico b/org.tizen.common.feature/rootfiles/resources/icons/tizen-sdk-ide.ico
deleted file mode 100644 (file)
index 35e30a8..0000000
Binary files a/org.tizen.common.feature/rootfiles/resources/icons/tizen-sdk-ide.ico and /dev/null differ
diff --git a/org.tizen.common.verrari/.classpath b/org.tizen.common.verrari/.classpath
new file mode 100644 (file)
index 0000000..a885b9b
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry exported="true" kind="lib" path="lib/jsoup-1.6.3.jar"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="test/src"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.tizen.common.verrari/.project b/org.tizen.common.verrari/.project
new file mode 100644 (file)
index 0000000..6b5e763
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.tizen.common.verrari</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/org.tizen.common.verrari/.settings/org.eclipse.jdt.core.prefs b/org.tizen.common.verrari/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..c3c3ee1
--- /dev/null
@@ -0,0 +1,8 @@
+#Tue Jul 24 20:15:30 KST 2012
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/org.tizen.common.verrari/META-INF/MANIFEST.MF b/org.tizen.common.verrari/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..a3df065
--- /dev/null
@@ -0,0 +1,28 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.tizen.common.verrari
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.tizen.common.verrari.Activator
+Bundle-Vendor: %Bundle-Vendor
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.tizen.common
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: lib/jsoup-1.6.3.jar,
+ .
+Export-Package: org.jsoup,
+ org.jsoup.examples,
+ org.jsoup.helper,
+ org.jsoup.nodes,
+ org.jsoup.parser,
+ org.jsoup.safety,
+ org.jsoup.select,
+ org.tizen.common.verrari,
+ org.tizen.common.verrari.engine,
+ org.tizen.common.verrari.engine.freemarker,
+ org.tizen.common.verrari.engine.jsoup,
+ org.tizen.common.verrari.model,
+ org.tizen.common.verrari.target,
+ org.tizen.common.verrari.template
diff --git a/org.tizen.common.verrari/OSGI-INF/l10n/bundle.properties b/org.tizen.common.verrari/OSGI-INF/l10n/bundle.properties
new file mode 100644 (file)
index 0000000..c4f377d
--- /dev/null
@@ -0,0 +1,3 @@
+#Properties file for org.tizen.common.verrari
+Bundle-Vendor = Samsung Electronics
+Bundle-Name = Tizen Verrari - Template Engine
\ No newline at end of file
diff --git a/org.tizen.common.verrari/about.html b/org.tizen.common.verrari/about.html
new file mode 100644 (file)
index 0000000..e96d835
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>May, 2011</p>
+<h3>Tizen SDK</h3>
+
+<p><a href="http://www.tizen.org/" target="_blank">Tizen SDK</a> 
+is a set of Eclipse plug-ins that helps programmers to develop applications for 
+the mobile platform.</p>
+
+<h3>License</h3>
+
+<p>See <a href="about_files/LICENSE-2.0.htm">Apache License, Version 2.0</a>.</p>
+
+<h3>Third Party Content</h3>
+
+<p>The Content includes items that have been sourced from third parties as set out below. If you did not
+receive this Content directly from the Eclipse Foundation, the following is provided for informational
+purposes only, and you should look to the Redistributor's license for terms and conditions of use.</p>
+
+<h4>jsoup</h4>
+<p>
+jsoup is a Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulating data, using the best of DOM, CSS, and jquery-like methods
+</p>
+
+<p>
+A copy of the license is included in <a href="about_files/jsoup-LICENSE.txt">about_files/jsoup-LICENSE.txt</a>. The home page is located at:
+<ul>
+<a href="http://jsoup.org/">http://jsoup.org/</a>
+</ul>
+</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/org.tizen.common.verrari/about_files/LICENSE-2.0.htm b/org.tizen.common.verrari/about_files/LICENSE-2.0.htm
new file mode 100644 (file)
index 0000000..f7ca656
--- /dev/null
@@ -0,0 +1,191 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+  <head>
+    <title>Apache License, Version 2.0</title>
+
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+    <meta property="og:image" content="http://www.apache.org/images/asf_logo.gif" />
+
+    <link rel="stylesheet" type="text/css" media="screen" href="/css/style.css">
+    <link rel="stylesheet" type="text/css" media="screen" href="/css/code.css">
+
+    <script type="text/javascript" src="/js/jquery.js"></script>
+    <script type="text/javascript" src="/js/apache_boot.js"></script>
+
+    
+
+    
+    <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file to you under the Apache License, Version 2.0 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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. -->
+  </head>
+
+  <body>
+    <div id="page" class="container_16">
+      <div id="header" class="grid_8">
+        <h1>The Apache Software Foundation</h1>
+        <h2>Apache License, Version 2.0</h2>
+      </div>
+
+      <div class="clear"></div>
+      <div id="content" class="grid_16"><div class="section-content"><p>Apache License<br></br>Version 2.0, January 2004<br></br>
+<a href="http://www.apache.org/licenses/">http://www.apache.org/licenses/</a> </p>
+<p>TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION</p>
+<p><strong><a name="definitions">1. Definitions</a></strong>.</p>
+<p>"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.</p>
+<p>"Licensor" shall mean the copyright owner or entity authorized by the
+copyright owner that is granting the License.</p>
+<p>"Legal Entity" shall mean the union of the acting entity and all other
+entities that control, are controlled by, or are under common control with
+that entity. For the purposes of this definition, "control" means (i) the
+power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty
+percent (50%) or more of the outstanding shares, or (iii) beneficial
+ownership of such entity.</p>
+<p>"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.</p>
+<p>"Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation source,
+and configuration files.</p>
+<p>"Object" form shall mean any form resulting from mechanical transformation
+or translation of a Source form, including but not limited to compiled
+object code, generated documentation, and conversions to other media types.</p>
+<p>"Work" shall mean the work of authorship, whether in Source or Object form,
+made available under the License, as indicated by a copyright notice that
+is included in or attached to the work (an example is provided in the
+Appendix below).</p>
+<p>"Derivative Works" shall mean any work, whether in Source or Object form,
+that is based on (or derived from) the Work and for which the editorial
+revisions, annotations, elaborations, or other modifications represent, as
+a whole, an original work of authorship. For the purposes of this License,
+Derivative Works shall not include works that remain separable from, or
+merely link (or bind by name) to the interfaces of, the Work and Derivative
+Works thereof.</p>
+<p>"Contribution" shall mean any work of authorship, including the original
+version of the Work and any modifications or additions to that Work or
+Derivative Works thereof, that is intentionally submitted to Licensor for
+inclusion in the Work by the copyright owner or by an individual or Legal
+Entity authorized to submit on behalf of the copyright owner. For the
+purposes of this definition, "submitted" means any form of electronic,
+verbal, or written communication sent to the Licensor or its
+representatives, including but not limited to communication on electronic
+mailing lists, source code control systems, and issue tracking systems that
+are managed by, or on behalf of, the Licensor for the purpose of discussing
+and improving the Work, but excluding communication that is conspicuously
+marked or otherwise designated in writing by the copyright owner as "Not a
+Contribution."</p>
+<p>"Contributor" shall mean Licensor and any individual or Legal Entity on
+behalf of whom a Contribution has been received by Licensor and
+subsequently incorporated within the Work.</p>
+<p><strong><a name="copyright">2. Grant of Copyright License</a></strong>. Subject to the
+terms and conditions of this License, each Contributor hereby grants to You
+a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+copyright license to reproduce, prepare Derivative Works of, publicly
+display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.</p>
+<p><strong><a name="patent">3. Grant of Patent License</a></strong>. Subject to the terms
+and conditions of this License, each Contributor hereby grants to You a
+perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+(except as stated in this section) patent license to make, have made, use,
+offer to sell, sell, import, and otherwise transfer the Work, where such
+license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by
+combination of their Contribution(s) with the Work to which such
+Contribution(s) was submitted. If You institute patent litigation against
+any entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that the Work or a Contribution incorporated within the Work constitutes
+direct or contributory patent infringement, then any patent licenses
+granted to You under this License for that Work shall terminate as of the
+date such litigation is filed.</p>
+<p><strong><a name="redistribution">4. Redistribution</a></strong>. You may reproduce and
+distribute copies of the Work or Derivative Works thereof in any medium,
+with or without modifications, and in Source or Object form, provided that
+You meet the following conditions:</p>
+<ol>
+<li>
+<p>You must give any other recipients of the Work or Derivative Works a
+copy of this License; and</p>
+</li>
+<li>
+<p>You must cause any modified files to carry prominent notices stating
+that You changed the files; and</p>
+</li>
+<li>
+<p>You must retain, in the Source form of any Derivative Works that You
+distribute, all copyright, patent, trademark, and attribution notices from
+the Source form of the Work, excluding those notices that do not pertain to
+any part of the Derivative Works; and</p>
+</li>
+<li>
+<p>If the Work includes a "NOTICE" text file as part of its distribution,
+then any Derivative Works that You distribute must include a readable copy
+of the attribution notices contained within such NOTICE file, excluding
+those notices that do not pertain to any part of the Derivative Works, in
+at least one of the following places: within a NOTICE text file distributed
+as part of the Derivative Works; within the Source form or documentation,
+if provided along with the Derivative Works; or, within a display generated
+by the Derivative Works, if and wherever such third-party notices normally
+appear. The contents of the NOTICE file are for informational purposes only
+and do not modify the License. You may add Your own attribution notices
+within Derivative Works that You distribute, alongside or as an addendum to
+the NOTICE text from the Work, provided that such additional attribution
+notices cannot be construed as modifying the License.
+You may add Your own copyright statement to Your modifications and may
+provide additional or different license terms and conditions for use,
+reproduction, or distribution of Your modifications, or for any such
+Derivative Works as a whole, provided Your use, reproduction, and
+distribution of the Work otherwise complies with the conditions stated in
+this License.</p>
+</li>
+</ol>
+<p><strong><a name="contributions">5. Submission of Contributions</a></strong>. Unless You
+explicitly state otherwise, any Contribution intentionally submitted for
+inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the
+terms of any separate license agreement you may have executed with Licensor
+regarding such Contributions.</p>
+<p><strong><a name="trademarks">6. Trademarks</a></strong>. This License does not grant
+permission to use the trade names, trademarks, service marks, or product
+names of the Licensor, except as required for reasonable and customary use
+in describing the origin of the Work and reproducing the content of the
+NOTICE file.</p>
+<p><strong><a name="no-warranty">7. Disclaimer of Warranty</a></strong>. Unless required by
+applicable law or agreed to in writing, Licensor provides the Work (and
+each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including,
+without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You
+are solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise
+of permissions under this License.</p>
+<p><strong><a name="no-liability">8. Limitation of Liability</a></strong>. In no event and
+under no legal theory, whether in tort (including negligence), contract, or
+otherwise, unless required by applicable law (such as deliberate and
+grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special,
+incidental, or consequential damages of any character arising as a result
+of this License or out of the use or inability to use the Work (including
+but not limited to damages for loss of goodwill, work stoppage, computer
+failure or malfunction, or any and all other commercial damages or losses),
+even if such Contributor has been advised of the possibility of such
+damages.</p>
+<p><strong><a name="additional">9. Accepting Warranty or Additional Liability</a></strong>.
+While redistributing the Work or Derivative Works thereof, You may choose
+to offer, and charge a fee for, acceptance of support, warranty, indemnity,
+or other liability obligations and/or rights consistent with this License.
+However, in accepting such obligations, You may act only on Your own behalf
+and on Your sole responsibility, not on behalf of any other Contributor,
+and only if You agree to indemnify, defend, and hold each Contributor
+harmless for any liability incurred by, or claims asserted against, such
+Contributor by reason of your accepting any such warranty or additional
+liability.</p>
+<p>END OF TERMS AND CONDITIONS</p>
+
+    <div class="clear"></div>
+    
+    </div>
+    <div id="copyright" class="container_16">
+      <p>Copyright &#169; 2011 The Apache Software Foundation, Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.<br/>Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
+    </div>
+  </body>
+</html>
diff --git a/org.tizen.common.verrari/about_files/jsoup-LICENSE.txt b/org.tizen.common.verrari/about_files/jsoup-LICENSE.txt
new file mode 100644 (file)
index 0000000..fda732e
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License\r
+\r
+Copyright (c) 2009, 2010, 2011, 2012 Jonathan Hedley <jonathan@hedley.net>\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy\r
+of this software and associated documentation files (the "Software"), to deal\r
+in the Software without restriction, including without limitation the rights\r
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+copies of the Software, and to permit persons to whom the Software is\r
+furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in\r
+all copies or substantial portions of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+THE SOFTWARE.
\ No newline at end of file
diff --git a/org.tizen.common.verrari/build.properties b/org.tizen.common.verrari/build.properties
new file mode 100644 (file)
index 0000000..e4e272e
--- /dev/null
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               template/,\
+               about.html,\
+               about_files/,\
+               OSGI-INF/,\
+               lib/jsoup-1.6.3.jar
diff --git a/org.tizen.common.verrari/lib/jsoup-1.6.3.jar b/org.tizen.common.verrari/lib/jsoup-1.6.3.jar
new file mode 100644 (file)
index 0000000..b3421d5
Binary files /dev/null and b/org.tizen.common.verrari/lib/jsoup-1.6.3.jar differ
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/Activator.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/Activator.java
new file mode 100644 (file)
index 0000000..590aabf
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+    // The plug-in ID
+    public static final String PLUGIN_ID = "org.tizen.common.verrari"; //$NON-NLS-1$
+
+    // The shared instance
+    private static Activator plugin;
+
+    /**
+     * The constructor
+     */
+    public Activator() {
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    public void start(BundleContext context) throws Exception {
+        super.start(context);
+        plugin = this;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext context) throws Exception {
+        plugin = null;
+        super.stop(context);
+    }
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static Activator getDefault() {
+        return plugin;
+    }
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/AbstractTemplateEngine.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/AbstractTemplateEngine.java
new file mode 100644 (file)
index 0000000..7aafb07
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.engine;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.tizen.common.verrari.model.IModel;
+import org.tizen.common.verrari.model.IModelProvider;
+import org.tizen.common.verrari.model.StaticModelProvider;
+import org.tizen.common.verrari.target.TargetGroup;
+import org.tizen.common.verrari.target.TargetUnit;
+import org.tizen.common.verrari.template.ITemplate;
+import org.tizen.common.verrari.template.ITemplateProvider;
+import org.tizen.common.verrari.template.StaticTemplateProvider;
+
+/**
+ * AbstractTemplateEngine.
+ *
+ * Initialization for ITemplateProvider, IModelProvider and sharedVariables.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public abstract class AbstractTemplateEngine implements ITemplateEngine {
+
+    protected IModelProvider modelProvider;
+    protected ITemplateProvider templateProvider;
+    protected HashMap<Object, Object> sharedVariables;
+
+    public AbstractTemplateEngine() {
+        modelProvider = new StaticModelProvider();
+        templateProvider = new StaticTemplateProvider();
+        sharedVariables = new HashMap<Object, Object>();
+    }
+
+    @Override
+    public void setTemplate(String key, ITemplate template) {
+        templateProvider.addTemplate(key, template);
+    }
+
+    @Override
+    public ITemplate getTemplate(String key) {
+        return templateProvider.getTemplate(key);
+    }
+
+    @Override
+    public ITemplateProvider getTemplateProvider() {
+        return templateProvider;
+    }
+
+    @Override
+    public void setModel(String key, IModel model) {
+        modelProvider.addModel(key, model);
+    }
+
+    @Override
+    public IModel getModel(String key) {
+        return modelProvider.getModel(key);
+    }
+
+    @Override
+    public IModelProvider getModelProvider() {
+        return modelProvider;
+    }
+
+    @Override
+    public void generate(TargetUnit unit) throws Exception {
+        applySharedVariable();
+    }
+
+    @Override
+    public void genearteGroup(TargetGroup group) throws Exception {
+        if (!group.isEmpty()) {
+            List<TargetUnit> targetList = group.getTargetUnits();
+            for (TargetUnit unit : targetList) {
+                generate(unit);
+            }
+        }
+    }
+
+    @Override
+    public void setSharedVariable(Object key, Object value) {
+        sharedVariables.put(key, value);
+    }
+
+    @Override
+    public Object getSharedVariable(Object key) {
+        return sharedVariables.get(key);
+    }
+
+    @Override
+    public void clearSharedVariable() {
+        sharedVariables.clear();
+    }
+
+    public void applySharedVariable() {
+        Map<String, IModel> models = getModelProvider().getModels();
+        for (IModel model : models.values()) {
+            for (Object key : sharedVariables.keySet()) {
+                model.put(key, sharedVariables.get(key));
+            }
+        }
+    }
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/ITemplateEngine.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/ITemplateEngine.java
new file mode 100644 (file)
index 0000000..73932ef
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.engine;
+
+import org.tizen.common.verrari.model.IModel;
+import org.tizen.common.verrari.model.IModelProvider;
+import org.tizen.common.verrari.target.TargetGroup;
+import org.tizen.common.verrari.target.TargetUnit;
+import org.tizen.common.verrari.template.ITemplate;
+import org.tizen.common.verrari.template.ITemplateProvider;
+
+/**
+ * ITemplateEngine.
+ *
+ * Common Template Engine Interface
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public interface ITemplateEngine {
+
+    public void setTemplate(String key, ITemplate template);
+    public ITemplate getTemplate(String key);
+    public ITemplateProvider getTemplateProvider();
+
+    public void setModel(String key, IModel model);
+    public IModel getModel(String key);
+    public IModelProvider getModelProvider();
+
+    public void generate(TargetUnit unit) throws Exception;
+    public void genearteGroup(TargetGroup group) throws Exception;
+
+    public void setSharedVariable(Object key, Object value);
+    public Object getSharedVariable(Object key);
+    public void clearSharedVariable();
+    public String getEngineVersion();
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/TemplateEngineFactory.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/TemplateEngineFactory.java
new file mode 100644 (file)
index 0000000..ea1cc13
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.engine;
+
+import org.tizen.common.Factory;
+import org.tizen.common.FactoryWithArgument;
+import org.tizen.common.verrari.engine.freemarker.FreemarkerTemplateEngine;
+import org.tizen.common.verrari.engine.jsoup.JsoupTemplateEngine;
+
+/**
+ * TemplateEngineFactory.
+ *
+ * Create to template engine.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+@SuppressWarnings("rawtypes")
+public class TemplateEngineFactory implements Factory<ITemplateEngine> ,FactoryWithArgument<ITemplateEngine, Class> {
+
+    protected static Factory<ITemplateEngine> instance;
+    static {
+        instance = new TemplateEngineFactory();
+    }
+
+    /**
+     * get template engine factory instance.
+     *
+     * @return TemplateEngineFactory
+     */
+    public static Factory<ITemplateEngine> getInstance() {
+        return instance;
+    }
+
+    /**
+     * Create Default template engine
+     *
+     * @return ITemplateEngine {@link ITemplateEngine}
+     */
+    @Override
+    public ITemplateEngine create() {
+        return new FreemarkerTemplateEngine();
+    }
+
+    /**
+     * Create template engine
+     *
+     * @param engineClass TemplateEngineClass
+     * @return ITemplateEngine {@link ITemplateEngine}
+     */
+    @Override
+    public ITemplateEngine create(Class engineClass) {
+        if (FreemarkerTemplateEngine.class.equals(engineClass)) {
+            return new FreemarkerTemplateEngine();
+        } else if (JsoupTemplateEngine.class.equals(engineClass)) {
+            return new JsoupTemplateEngine();
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/freemarker/FreemarkerTemplateEngine.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/freemarker/FreemarkerTemplateEngine.java
new file mode 100644 (file)
index 0000000..00c9314
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.engine.freemarker;
+
+import java.io.BufferedWriter;
+import java.util.Locale;
+
+import org.tizen.common.util.FreeMarkerUtil;
+import org.tizen.common.verrari.engine.AbstractTemplateEngine;
+import org.tizen.common.verrari.model.MapModel;
+import org.tizen.common.verrari.target.TargetUnit;
+import org.tizen.common.verrari.template.FileTemplate;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+
+
+/**
+ * FreemarkerTemplateEngine.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public class FreemarkerTemplateEngine extends AbstractTemplateEngine {
+
+    protected Configuration cfg;
+
+    public FreemarkerTemplateEngine() {
+         cfg = FreeMarkerUtil.getDefaultConfiguration();
+    }
+
+    public Configuration getConfiguration() {
+        return cfg;
+    }
+
+    @Override
+    public void generate(TargetUnit unit) throws Exception {
+        super.generate(unit);
+        MapModel model = (MapModel) getModel(unit.getModelKey());
+        if (null == model) {
+            throw new Exception("Model is Empty.");
+        }
+
+        FileTemplate template = (FileTemplate) getTemplate(unit.getTemplateKey());
+        if (null == template) {
+            throw new Exception("Template is Empty.");
+        }
+        Template freemarkerTemplate = cfg.getTemplate(template.getContainer().getPath());
+        cfg.setEncoding(Locale.getDefault(), unit.getEncoding());
+
+        freemarkerTemplate.process(model.getContainer(), new BufferedWriter(unit.getWriter()));
+        //freemarkertemp.process(model.getModel(), new OutputStreamWriter(System.out));
+
+        // TODO:: XML Parser
+//        Map<String, Object> root = new HashMap<String, Object>();
+//        NodeModel model2 = NodeModel.parse(new File("template/html/test.xml"));
+//        root.put("doc", model2);
+
+    }
+
+    @SuppressWarnings("static-access")
+       @Override
+    public String getEngineVersion() {
+        return cfg.getVersionNumber();
+    }
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/jsoup/JsoupTemplateEngine.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/engine/jsoup/JsoupTemplateEngine.java
new file mode 100644 (file)
index 0000000..21cb6ca
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.engine.jsoup;
+
+import java.io.File;
+import java.io.Writer;
+import java.util.Map;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Attribute;
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.tizen.common.verrari.engine.AbstractTemplateEngine;
+import org.tizen.common.verrari.model.MapModel;
+import org.tizen.common.verrari.target.TargetUnit;
+import org.tizen.common.verrari.template.FileTemplate;
+
+/**
+ * JsoupTemplateEngine.
+ * HTML Parser.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public class JsoupTemplateEngine extends AbstractTemplateEngine {
+
+    public JsoupTemplateEngine() {
+    }
+
+    @Override
+    public void generate(TargetUnit unit) throws Exception {
+        super.generate(unit);
+
+        MapModel model = (MapModel) getModel(unit.getModelKey());
+        if (null == model) {
+            throw new Exception("Model is Empty.");
+        }
+
+        FileTemplate template = (FileTemplate) getTemplate(unit.getTemplateKey());
+        if (null == template) {
+            throw new Exception("Template is Empty.");
+        }
+
+        generate(template.getContainer(), (Map) model.getContainer(), template.getEncoding(), unit.getWriter());
+    }
+
+    public Document generate(File template, Map model, String encoding) throws Exception {
+        Document doc = Jsoup.parse(template, encoding);
+        Map<Object, Object> root = (Map<Object, Object>) model;
+        for (Map.Entry<Object, Object> entry : root.entrySet()) {
+            Elements elements = doc.select((String) entry.getKey());
+            if (!elements.isEmpty()) {
+                Element element = elements.get(0);
+                Object attr = entry.getValue() ;
+                if (attr instanceof Attribute) {
+                    element.attr(((Attribute) attr).getKey(), ((Attribute) attr).getValue());
+                } else if (attr instanceof Attributes){
+                    Attributes attributes = (Attributes) attr;
+                    for (Attribute attribute : attributes) {
+                        element.attr(attribute.getKey(), attribute.getValue());;
+                    }
+                } else {
+                    element.attr((String)entry.getKey(), (String)attr);
+                }
+            }
+        }
+        return doc;
+    }
+
+    public void generate(File template, Map model, String encoding, Writer write) throws Exception {
+        Document doc = generate(template, model, encoding);
+        write.write(doc.html());
+        write.flush();
+    }
+
+    @Override
+    public String getEngineVersion() {
+        // FIXME::
+        // Platform.getBundle("org.jsoup").getHeaders().get("Bundle-Version");
+        return "1.6.3";
+    }
+
+}
\ No newline at end of file
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/model/IModel.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/model/IModel.java
new file mode 100644 (file)
index 0000000..2c01b78
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.model;
+
+/**
+ * IModel.
+ *
+ * Common Model Interface
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public interface IModel {
+
+    public void put(Object key, Object value);
+    public Object get(Object key);
+    public Object getContainer();
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/model/IModelProvider.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/model/IModelProvider.java
new file mode 100644 (file)
index 0000000..1981462
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.model;
+
+import java.util.Map;
+
+/**
+ * IModelProvider.
+ *
+ * Management for models.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public interface IModelProvider {
+
+    public void addModel(String key, IModel model);
+    public IModel getModel(String key);
+    public IModel removeModel(String key);
+    public Map<String, IModel> getModels();
+    public boolean isEmpty();
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/model/MapModel.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/model/MapModel.java
new file mode 100644 (file)
index 0000000..25986c6
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.model;
+
+import java.util.Map;
+
+/**
+ * MapModel.
+ *
+ * IModel implementation by map.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public class MapModel implements IModel {
+
+    protected Map<Object, Object> model;
+
+    public MapModel(Map<Object, Object> map) {
+        this.model = map;
+    }
+
+    @Override
+    public Object get(Object key) {
+        return model.get(key);
+    }
+
+    @Override
+    public Object getContainer() {
+        return model;
+    }
+
+    @Override
+    public void put(Object key, Object value) {
+        model.put(key, value);
+    }
+
+    public Object remove(Object key) {
+        return model.remove(key);
+    }
+
+    public boolean isEmpty() {
+        return model.isEmpty();
+    }
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/model/StaticModelProvider.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/model/StaticModelProvider.java
new file mode 100644 (file)
index 0000000..1932fb1
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * StaticModelProvider.
+ *
+ * Manage the models.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public class StaticModelProvider implements IModelProvider {
+
+    protected Map<String, IModel> models;
+
+    public StaticModelProvider() {
+        models = new HashMap<String, IModel>();
+    }
+
+    @Override
+    public void addModel(String key, IModel model) {
+        models.put(key, model);
+    }
+
+    @Override
+    public IModel getModel(String key) {
+        return models.get(key);
+    }
+
+    @Override
+    public IModel removeModel(String key) {
+        return models.remove(key);
+    }
+
+    @Override
+    public Map<String, IModel> getModels() {
+        return models;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return models.isEmpty();
+    }
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/target/TargetGroup.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/target/TargetGroup.java
new file mode 100644 (file)
index 0000000..3135c74
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.target;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TargetGroup
+ *
+ * Targetunits management.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public class TargetGroup {
+
+    protected List<TargetUnit> units;
+
+    public TargetGroup() {
+        units = new ArrayList<TargetUnit>();
+    }
+
+    public List<TargetUnit> getTargetUnits() {
+        return units;
+    }
+
+    public boolean addTargetUnit(TargetUnit unit) {
+       if (unit != null) {
+               return units.add(unit);
+       }
+       return false;
+    }
+
+    public boolean removeTargetunit(TargetUnit unit) {
+       if (unit != null) {
+               return units.remove(unit);
+       }
+       return false;
+    }
+
+    public boolean isEmpty() {
+        return units.isEmpty();
+    }
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/target/TargetUnit.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/target/TargetUnit.java
new file mode 100644 (file)
index 0000000..961aed1
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.target;
+
+import java.io.Writer;
+
+/**
+ * TargetUnit.
+ *
+ * Single file management.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public class TargetUnit {
+
+    private String templateKey;
+    private String modelKey;
+    private Writer out;
+    private String encoding;
+
+    public TargetUnit(String templateKey, String modelKey, Writer out, String encoding) {
+        if (templateKey == null || templateKey.isEmpty() || modelKey == null || modelKey.isEmpty() || out == null) {
+            throw new IllegalArgumentException();
+        }
+
+        if (null == encoding || encoding.isEmpty()) {
+            encoding = System.getProperty("file.encoding");
+        }
+
+        this.templateKey = templateKey;
+        this.modelKey = modelKey;
+        this.out = out;
+        this.encoding = encoding;
+    }
+
+    public void setTemplateKey(String templateKey) {
+        if (templateKey != null && !templateKey.isEmpty()) {
+            this.templateKey = templateKey;
+        }
+    }
+
+    public String getTemplateKey() {
+        return templateKey;
+    }
+
+    public void setModelKey(String modelKey) {
+        if (modelKey != null && !modelKey.isEmpty()) {
+            this.modelKey = modelKey;
+        }
+    }
+
+    public String getModelKey() {
+        return modelKey;
+    }
+
+    public void setWriter(Writer out) {
+        if (out != null) {
+            this.out = out;
+        }
+    }
+
+    public Writer getWriter() {
+        return out;
+    }
+
+    public void setEncoding(String encoding) {
+        if (encoding != null && !encoding.isEmpty()) {
+            this.encoding = encoding;
+        }
+    }
+
+    public String getEncoding() {
+        return encoding;
+    }
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/template/FileTemplate.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/template/FileTemplate.java
new file mode 100644 (file)
index 0000000..c30457d
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.template;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * FileTemplate.
+ *
+ * ITemplate implementation by file.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public class FileTemplate implements ITemplate {
+
+    protected File file;
+    protected String encoding;
+
+    public FileTemplate(File file) {
+        this.file = file;
+        this.encoding = System.getProperty("file.encoding"); //$NON-NLS-1$
+    }
+
+    @Override
+    public File getContainer() {
+        return file;
+    }
+
+    @Override
+    public String getEncoding() {
+        return encoding;
+    }
+
+    @Override
+    public InputStream open() throws IOException {
+        return new FileInputStream(file);
+    }
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/template/ITemplate.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/template/ITemplate.java
new file mode 100644 (file)
index 0000000..0f6f8e6
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.template;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * ITemplate.
+ *
+ * Common Template Interface
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public interface ITemplate {
+
+    public Object getContainer();
+    public String getEncoding();
+    public InputStream open() throws IOException;
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/template/ITemplateProvider.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/template/ITemplateProvider.java
new file mode 100644 (file)
index 0000000..e1aba9a
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.template;
+
+import java.io.File;
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * ITemplateProvider.
+ *
+ * Management for template.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public interface ITemplateProvider {
+
+    public void addTemplate(String key, ITemplate template);
+    public void addTemplate(String key, URI templateURI);
+    public void addTemplate(String key, File templateFile);
+    public ITemplate getTemplate(String key);
+    public ITemplate removeTemplate(String key);
+    public Map<String, ITemplate> getTemplates();
+    public boolean isEmpty();
+
+}
diff --git a/org.tizen.common.verrari/src/org/tizen/common/verrari/template/StaticTemplateProvider.java b/org.tizen.common.verrari/src/org/tizen/common/verrari/template/StaticTemplateProvider.java
new file mode 100644 (file)
index 0000000..8b9e573
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.template;
+
+import java.io.File;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * StaticTemplateProvider.
+ *
+ * Manage the templates.
+ *
+ * @author ChangHyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public class StaticTemplateProvider implements ITemplateProvider {
+
+    protected Map<String, ITemplate> templates;
+
+    public StaticTemplateProvider() {
+        templates = new HashMap<String, ITemplate>();
+    }
+
+    @Override
+    public void addTemplate(String key, ITemplate template) {
+        templates.put(key, template);
+    }
+
+    @Override
+    public void addTemplate(String key, URI templateURI) {
+        File file = new File(templateURI);
+        addTemplate(key, file);
+    }
+
+    @Override
+    public void addTemplate(String key, File templateFile) {
+        ITemplate fileTemplate = new FileTemplate(templateFile);
+        templates.put(key, fileTemplate);
+    }
+
+    @Override
+    public ITemplate getTemplate(String key) {
+        return templates.get(key);
+    }
+
+    @Override
+    public ITemplate removeTemplate(String key) {
+        return templates.remove(key);
+    }
+
+    @Override
+    public Map<String, ITemplate> getTemplates() {
+        return templates;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return templates.isEmpty();
+    }
+
+}
diff --git a/org.tizen.common.verrari/template/html/description.ftl b/org.tizen.common.verrari/template/html/description.ftl
new file mode 100644 (file)
index 0000000..b958b39
--- /dev/null
@@ -0,0 +1,3 @@
+<!------------------------------------------------------------------------------------------------
+ Copyright ${description_date!"2012"} ${description_author!"author"} All rights reserved.
+------------------------------------------------------------------------------------------------->
\ No newline at end of file
diff --git a/org.tizen.common.verrari/template/html/index_html.ftl b/org.tizen.common.verrari/template/html/index_html.ftl
new file mode 100644 (file)
index 0000000..3e950db
--- /dev/null
@@ -0,0 +1,36 @@
+<#include "description.ftl">
+
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, target-densityDpi=device-dpi"/>
+    <meta name="description" content="${meta_description_content!"Tizen template generated by Tizen Web IDE"}"/>
+
+    <title>${index_html_title!'Title'}</title>
+
+<#if TizenWebUIFW_Enable?exists>
+${head_script_tizenwebuifw!""}
+
+        <!--NOTE:
+        Additional scripts and css files are to be placed here.
+        You can use jQuery namespace($) and all functionalities in jQuery
+        in your script.  For example:
+
+            <script src="main.js"></script>
+            <link rel="stylesheet" href="my.css">
+
+        When you want to manipulate elements in your code, you have to
+        use domReady for your code to work properly, like this;
+
+            domReady(function(){ ... });
+        -->
+</#if>
+    <script type="text/javascript" src="./js/main.js"></script>
+    <link rel="stylesheet" type="text/css" href="./css/style.css"/>
+</head>
+
+<body>
+<#include "test_html_body.ftl">
+</body>
+</html>
diff --git a/org.tizen.common.verrari/template/html/index_html_body.ftl b/org.tizen.common.verrari/template/html/index_html_body.ftl
new file mode 100644 (file)
index 0000000..363eba5
--- /dev/null
@@ -0,0 +1,77 @@
+<#if TizenWebUIFW_Enable?exists>
+    <#if test_html_body_tizenwebuifw_single?exists>
+        <div data-role="page">
+            <div data-role="header" data-position="fixed">
+                <h1>Single-Page Application </h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <p>This is a single page boilerplate template that you can copy to build your first Tizen Web UI Framework page.</p>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Footer content</h4>
+            </div><!-- /footer -->
+        </div><!-- /page -->
+    <#elseif test_html_body_tizenwebuifw_multi?exists>
+        <!-- Start of first page: #one -->
+        <div data-role="page" id="one">
+            <div data-role="header" data-position="fixed">
+                <h1>Multi-Page Application</h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <h2>One</h2>
+                <p>
+                    This is a multi-page boilerplate template that you can copy to build
+                    your first Tizen Web UI Framework page. This template contains multiple "page"
+                    containers inside.
+                </p>
+                <p>
+                    You link to internal pages by referring to the ID of the page you
+                    want to show. For example, to <a href="#two">link</a> to the page
+                    with an ID of "two", my link would have a
+                    <code>href="#two"</code>
+                    in the code.
+                </p>
+                <h3>Show internal pages:</h3>
+                <p><a href="#two" data-role="button">Show page "two"</a></p>
+                <p><a href="#popup"  data-role="button" aria-haspopup="true" data-rel="popupwindow">Show page "popup" (as a dialog)</a></p>
+
+                <div id="popup" data-role="popupwindow" data-style="center_title_1btn">
+                    <p data-role="title">Popup</p>
+                    <p data-role="text">Pop-up dialog box, a child window that blocks user interact to the parent windows</p>
+                    <div data-role="button-bg"><a href="#" data-role="button" onclick="javascript:$('#popup').popupwindow('close');">Close</a></div>
+                </div>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Page Footer</h4>
+            </div><!-- /footer -->
+        </div><!-- /page one -->
+
+        <!-- Start of second page: #two -->
+        <div data-role="page" id="two">
+            <div data-role="header" data-position="fixed">
+                <h1>Two</h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <h2>Two</h2>
+                <p>I have an id of "two" on my page container. I'm the second
+                    page container in this multi-page template.</p>
+                <p><a href="#one" data-direction="reverse" data-role="button">Back to page "one"</a></p>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Page Footer</h4>
+            </div><!-- /footer -->
+        </div><!-- /page two -->
+    </#if>
+<#else>
+    <header>
+    </header>
+
+    <footer>
+    </footer>
+</#if>
diff --git a/org.tizen.common.verrari/template/html/test.xml b/org.tizen.common.verrari/template/html/test.xml
new file mode 100644 (file)
index 0000000..c34813c
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<index_html_title>Title</index_html_title>
diff --git a/org.tizen.common.verrari/template/js/description.ftl b/org.tizen.common.verrari/template/js/description.ftl
new file mode 100644 (file)
index 0000000..c314648
--- /dev/null
@@ -0,0 +1,3 @@
+/**
+ * Copyright ${description_date!"2012"} ${description_author!"author"} All rights reserved.
+ */
diff --git a/org.tizen.common.verrari/template/js/main_js.ftl b/org.tizen.common.verrari/template/js/main_js.ftl
new file mode 100644 (file)
index 0000000..3c8cdc8
--- /dev/null
@@ -0,0 +1,10 @@
+<#if jsDescription?exists>
+<#include "template/js/description.ftl">
+</#if>
+//Initialize function
+var init = function () {
+    // TODO:: Do your initialization job
+    console.log("init() called");
+};
+// window.onload can work without <body onload="">
+window.onload = init;
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/TemplateEngineFactoryTest.java b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/TemplateEngineFactoryTest.java
new file mode 100644 (file)
index 0000000..016f00b
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.engine;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.tizen.common.Factory;
+import org.tizen.common.verrari.engine.freemarker.FreemarkerTemplateEngine;
+import org.tizen.common.verrari.engine.jsoup.JsoupTemplateEngine;
+
+/**
+ * TemplateEngineFactoryTest.
+ *
+ * Test case for {@link TemplateEngineFactory}
+ *
+ * @author Changhyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *
+ * @see TemplateEngineFactory
+ *
+ */
+public class TemplateEngineFactoryTest {
+
+    /**
+     * Test {@link TemplateEngineFactory#getInstance()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TemplateEngineFactory#getInstance()
+     */
+    @Test
+    public void test_getInstance() throws Exception {
+        Factory<ITemplateEngine> engineFactory = TemplateEngineFactory.getInstance();
+        assertNotNull(engineFactory);
+    }
+
+    /**
+     * Test {@link TemplateEngineFactory#create()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TemplateEngineFactory#create()
+     */
+    @Test
+    public void test_create() throws Exception {
+        ITemplateEngine engine = TemplateEngineFactory.getInstance().create();
+        assertNotNull(engine);
+    }
+
+    /**
+     * Test {@link TemplateEngineFactory#create(Class)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TemplateEngineFactory#create(Class)
+     */
+    @Test
+    public void test_create2() throws Exception {
+        TemplateEngineFactory factory = new TemplateEngineFactory();
+        assertNull(factory.create(null));
+        assertNotNull(factory.create(FreemarkerTemplateEngine.class));
+        assertNotNull(factory.create(JsoupTemplateEngine.class));
+    }
+
+}
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/FreemarkerTemplateEngineTest.java b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/FreemarkerTemplateEngineTest.java
new file mode 100644 (file)
index 0000000..0dbf9dc
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.engine.freemarker;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.util.HashMap;
+
+import org.junit.Test;
+import org.tizen.common.verrari.model.MapModel;
+import org.tizen.common.verrari.target.TargetGroup;
+import org.tizen.common.verrari.target.TargetUnit;
+import org.tizen.common.verrari.template.FileTemplate;
+import org.tizen.common.verrari.template.ITemplate;
+
+/**
+ * FreemarkerTemplateEngineTest.
+ *
+ * Test case for {@link FreemarkerTemplateEngine}
+ *
+ * @author Changhyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *
+ * @see FreemarkerTemplateEngine
+ *
+ */
+public class FreemarkerTemplateEngineTest {
+
+    public String head = 
+            "<#if TizenWebUIFW_Default?exists>" + "\n" +
+            "    <script src=\"tizen-web-ui-fw/latest/js/jquery.js\"></script>" + "\n" +
+            "    <script src=\"tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js\"></script>" + "\n" +
+            "    <script src=\"tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js\" data-framework-theme=\"tizen-gray\" data-framework-viewport-scale=\"false\"></script>" + "\n" +
+            "<#elseif TizenWebUIFW_PATH?exists>" + "\n" +
+            "    <script src=\"${TizenWebUIFW_JQuery?default(\"/usr/share/tizen-web-ui-fw/latest/js/jquery.js\")}\"></script>" + "\n" +
+            "    <script src=\"${TizenWebUIFW_Libs?default(\"/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js\")}\"></script>" + "\n" +
+            "    <script src=\"${TizenWebUIFW_JS?default(\"/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js\")}\" data-framework-theme=\"${theme?default(\"tizen-gray\")}\" data-framework-viewport-scale=\"${scale?default(\"false\")}\"></script>" + "\n" +
+            "</#if>";
+
+    /**
+     * Test {@link FreemarkerTemplateEngine#generate(TargetUnit unit)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see FreemarkerTemplateEngine#generate(TargetUnit unit)
+     */
+    @Test
+    public void test_generate() throws Exception {
+        FreemarkerTemplateEngine engine = new FreemarkerTemplateEngine();
+        engine.setSharedVariable("description_date", "2012");
+        engine.setSharedVariable("description_author", "changhyun1.lee@samsung.com");
+
+        ITemplate template = new FileTemplate(new File("./test/src/org/tizen/common/verrari/engine/freemarker/test_html.ftl"));
+        engine.getTemplateProvider().addTemplate("testHtmlTemplate", template);
+
+        MapModel mapModel = new MapModel(new HashMap<Object, Object>());
+        mapModel.put("index_html_title", "Tizen Empty");
+        engine.getModelProvider().addModel("testEmptyModel", mapModel);
+
+        MapModel mapModel2 = new MapModel(new HashMap<Object, Object>());
+        mapModel2.put("index_html_title", "Tizen Web UI FW - Single");
+        mapModel2.put("TizenWebUIFW_Enable", "");
+        mapModel2.put("head_script_tizenwebuifw", head);
+        mapModel2.put("test_html_body_tizenwebuifw_single", "");
+        engine.getModelProvider().addModel("testTizenSingleModel", mapModel2);
+
+        MapModel mapModel3 = new MapModel(new HashMap<Object, Object>());
+        mapModel3.put("index_html_title", "Tizen Web UI FW - Multi");
+        mapModel3.put("TizenWebUIFW_Enable", "");
+        mapModel3.put("head_script_tizenwebuifw", head);
+        mapModel3.put("test_html_body_tizenwebuifw_multi", "");
+        engine.getModelProvider().addModel("testTizenMultiModel", mapModel3);
+
+        File destinationEmptyFile = new File("./test/src/org/tizen/common/verrari/engine/freemarker/test.html");
+        File destinationTizenSingleFile = new File("./test/src/org/tizen/common/verrari/engine/freemarker/testTizenSingle.html");
+        File destinationTizenMultiFile = new File("./test/src/org/tizen/common/verrari/engine/freemarker/testTizenMulti.html");
+
+        TargetGroup group = new TargetGroup();
+        group.addTargetUnit(new TargetUnit("testHtmlTemplate", "testEmptyModel", new OutputStreamWriter(new FileOutputStream(destinationEmptyFile)), "UTF-8"));
+        group.addTargetUnit(new TargetUnit("testHtmlTemplate", "testTizenSingleModel", new OutputStreamWriter(new FileOutputStream(destinationTizenSingleFile)), "UTF-8"));
+        group.addTargetUnit(new TargetUnit("testHtmlTemplate", "testTizenMultiModel", new OutputStreamWriter(new FileOutputStream(destinationTizenMultiFile)), "UTF-8"));
+
+        engine.genearteGroup(group);
+        //TargetUnit unit = new TargetUnit("testHtmlTemplate", "testHtmlModel", new OutputStreamWriter(System.out), "UTF-8");
+
+        ITemplate regenTemplate = new FileTemplate(new File("./test/src/org/tizen/common/verrari/engine/freemarker/testTizenSingle.html"));
+        engine.getTemplateProvider().addTemplate("regenHtmlTemplate", regenTemplate);
+        MapModel finalMapModel = new MapModel(new HashMap<Object, Object>());
+        finalMapModel.put("TizenWebUIFW_PATH", "");
+        engine.getModelProvider().addModel("testFinalMapModel", finalMapModel);
+        File finalTizenSingleFile = new File("./test/src/org/tizen/common/verrari/engine/freemarker/testTizenSingle2.html");
+        TargetUnit unit = new TargetUnit("regenHtmlTemplate", "testFinalMapModel", new OutputStreamWriter(new FileOutputStream(finalTizenSingleFile)), "UTF-8");
+        engine.generate(unit);
+
+//      description_date
+//      description_author
+//      head_script_tizen-web-ui-fw
+//      TizenWebUIFW_Enable
+//          test_html_body_tizenwebuifw_single
+//          test_html_body_tizenwebuifw_multi
+
+    }
+}
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/description.ftl b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/description.ftl
new file mode 100644 (file)
index 0000000..b958b39
--- /dev/null
@@ -0,0 +1,3 @@
+<!------------------------------------------------------------------------------------------------
+ Copyright ${description_date!"2012"} ${description_author!"author"} All rights reserved.
+------------------------------------------------------------------------------------------------->
\ No newline at end of file
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/test.html b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/test.html
new file mode 100644 (file)
index 0000000..bfce1b0
--- /dev/null
@@ -0,0 +1,24 @@
+<!------------------------------------------------------------------------------------------------
+ Copyright 2012 changhyun1.lee@samsung.com All rights reserved.
+------------------------------------------------------------------------------------------------->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, target-densityDpi=device-dpi"/>
+    <meta name="description" content="Tizen template generated by Tizen Web IDE"/>
+
+    <title>Tizen Empty</title>
+
+    <script type="text/javascript" src="./js/main.js"></script>
+    <link rel="stylesheet" type="text/css" href="./css/style.css"/>
+</head>
+
+<body>
+    <header>
+    </header>
+
+    <footer>
+    </footer>
+</body>
+</html>
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/testTizenMulti.html b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/testTizenMulti.html
new file mode 100644 (file)
index 0000000..7878669
--- /dev/null
@@ -0,0 +1,95 @@
+<!------------------------------------------------------------------------------------------------
+ Copyright 2012 changhyun1.lee@samsung.com All rights reserved.
+------------------------------------------------------------------------------------------------->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, target-densityDpi=device-dpi"/>
+    <meta name="description" content="Tizen template generated by Tizen Web IDE"/>
+
+    <title>Tizen Web UI FW - Multi</title>
+
+<#if TizenWebUIFW_Default?exists>
+    <script src="tizen-web-ui-fw/latest/js/jquery.js"></script>
+    <script src="tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js"></script>
+    <script src="tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js" data-framework-theme="tizen-gray" data-framework-viewport-scale="false"></script>
+<#elseif TizenWebUIFW_PATH?exists>
+    <script src="${TizenWebUIFW_JQuery?default("/usr/share/tizen-web-ui-fw/latest/js/jquery.js")}"></script>
+    <script src="${TizenWebUIFW_Libs?default("/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js")}"></script>
+    <script src="${TizenWebUIFW_JS?default("/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js")}" data-framework-theme="${theme?default("tizen-gray")}" data-framework-viewport-scale="${scale?default("false")}"></script>
+</#if>
+
+        <!--NOTE:
+        Additional scripts and css files are to be placed here.
+        You can use jQuery namespace($) and all functionalities in jQuery
+        in your script.  For example:
+
+            <script src="main.js"></script>
+            <link rel="stylesheet" href="my.css">
+
+        When you want to manipulate elements in your code, you have to
+        use domReady for your code to work properly, like this;
+
+            domReady(function(){ ... });
+        -->
+    <script type="text/javascript" src="./js/main.js"></script>
+    <link rel="stylesheet" type="text/css" href="./css/style.css"/>
+</head>
+
+<body>
+        <!-- Start of first page: #one -->
+        <div data-role="page" id="one">
+            <div data-role="header" data-position="fixed">
+                <h1>Multi-Page Application</h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <h2>One</h2>
+                <p>
+                    This is a multi-page boilerplate template that you can copy to build
+                    your first Tizen Web UI Framework page. This template contains multiple "page"
+                    containers inside.
+                </p>
+                <p>
+                    You link to internal pages by referring to the ID of the page you
+                    want to show. For example, to <a href="#two">link</a> to the page
+                    with an ID of "two", my link would have a
+                    <code>href="#two"</code>
+                    in the code.
+                </p>
+                <h3>Show internal pages:</h3>
+                <p><a href="#two" data-role="button">Show page "two"</a></p>
+                <p><a href="#popup"  data-role="button" aria-haspopup="true" data-rel="popupwindow">Show page "popup" (as a dialog)</a></p>
+
+                <div id="popup" data-role="popupwindow" data-style="center_title_1btn">
+                    <p data-role="title">Popup</p>
+                    <p data-role="text">Pop-up dialog box, a child window that blocks user interact to the parent windows</p>
+                    <div data-role="button-bg"><a href="#" data-role="button" onclick="javascript:$('#popup').popupwindow('close');">Close</a></div>
+                </div>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Page Footer</h4>
+            </div><!-- /footer -->
+        </div><!-- /page one -->
+
+        <!-- Start of second page: #two -->
+        <div data-role="page" id="two">
+            <div data-role="header" data-position="fixed">
+                <h1>Two</h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <h2>Two</h2>
+                <p>I have an id of "two" on my page container. I'm the second
+                    page container in this multi-page template.</p>
+                <p><a href="#one" data-direction="reverse" data-role="button">Back to page "one"</a></p>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Page Footer</h4>
+            </div><!-- /footer -->
+        </div><!-- /page two -->
+</body>
+</html>
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/testTizenSingle.html b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/testTizenSingle.html
new file mode 100644 (file)
index 0000000..8a6159f
--- /dev/null
@@ -0,0 +1,55 @@
+<!------------------------------------------------------------------------------------------------
+ Copyright 2012 changhyun1.lee@samsung.com All rights reserved.
+------------------------------------------------------------------------------------------------->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, target-densityDpi=device-dpi"/>
+    <meta name="description" content="Tizen template generated by Tizen Web IDE"/>
+
+    <title>Tizen Web UI FW - Single</title>
+
+<#if TizenWebUIFW_Default?exists>
+    <script src="tizen-web-ui-fw/latest/js/jquery.js"></script>
+    <script src="tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js"></script>
+    <script src="tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js" data-framework-theme="tizen-gray" data-framework-viewport-scale="false"></script>
+<#elseif TizenWebUIFW_PATH?exists>
+    <script src="${TizenWebUIFW_JQuery?default("/usr/share/tizen-web-ui-fw/latest/js/jquery.js")}"></script>
+    <script src="${TizenWebUIFW_Libs?default("/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js")}"></script>
+    <script src="${TizenWebUIFW_JS?default("/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js")}" data-framework-theme="${theme?default("tizen-gray")}" data-framework-viewport-scale="${scale?default("false")}"></script>
+</#if>
+
+        <!--NOTE:
+        Additional scripts and css files are to be placed here.
+        You can use jQuery namespace($) and all functionalities in jQuery
+        in your script.  For example:
+
+            <script src="main.js"></script>
+            <link rel="stylesheet" href="my.css">
+
+        When you want to manipulate elements in your code, you have to
+        use domReady for your code to work properly, like this;
+
+            domReady(function(){ ... });
+        -->
+    <script type="text/javascript" src="./js/main.js"></script>
+    <link rel="stylesheet" type="text/css" href="./css/style.css"/>
+</head>
+
+<body>
+        <div data-role="page">
+            <div data-role="header" data-position="fixed">
+                <h1>Single-Page Application </h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <p>This is a single page boilerplate template that you can copy to build your first Tizen Web UI Framework page.</p>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Footer content</h4>
+            </div><!-- /footer -->
+        </div><!-- /page -->
+</body>
+</html>
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/testTizenSingle2.html b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/testTizenSingle2.html
new file mode 100644 (file)
index 0000000..f3dd7fe
--- /dev/null
@@ -0,0 +1,49 @@
+<!------------------------------------------------------------------------------------------------
+ Copyright 2012 changhyun1.lee@samsung.com All rights reserved.
+------------------------------------------------------------------------------------------------->
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, target-densityDpi=device-dpi"/>
+    <meta name="description" content="Tizen template generated by Tizen Web IDE"/>
+
+    <title>Tizen Web UI FW - Single</title>
+
+    <script src="/usr/share/tizen-web-ui-fw/latest/js/jquery.js"></script>
+    <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js"></script>
+    <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js" data-framework-theme="tizen-gray" data-framework-viewport-scale="false"></script>
+
+        <!--NOTE:
+        Additional scripts and css files are to be placed here.
+        You can use jQuery namespace($) and all functionalities in jQuery
+        in your script.  For example:
+
+            <script src="main.js"></script>
+            <link rel="stylesheet" href="my.css">
+
+        When you want to manipulate elements in your code, you have to
+        use domReady for your code to work properly, like this;
+
+            domReady(function(){ ... });
+        -->
+    <script type="text/javascript" src="./js/main.js"></script>
+    <link rel="stylesheet" type="text/css" href="./css/style.css"/>
+</head>
+
+<body>
+        <div data-role="page">
+            <div data-role="header" data-position="fixed">
+                <h1>Single-Page Application </h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <p>This is a single page boilerplate template that you can copy to build your first Tizen Web UI Framework page.</p>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Footer content</h4>
+            </div><!-- /footer -->
+        </div><!-- /page -->
+</body>
+</html>
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/test_html.ftl b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/test_html.ftl
new file mode 100644 (file)
index 0000000..3e950db
--- /dev/null
@@ -0,0 +1,36 @@
+<#include "description.ftl">
+
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, target-densityDpi=device-dpi"/>
+    <meta name="description" content="${meta_description_content!"Tizen template generated by Tizen Web IDE"}"/>
+
+    <title>${index_html_title!'Title'}</title>
+
+<#if TizenWebUIFW_Enable?exists>
+${head_script_tizenwebuifw!""}
+
+        <!--NOTE:
+        Additional scripts and css files are to be placed here.
+        You can use jQuery namespace($) and all functionalities in jQuery
+        in your script.  For example:
+
+            <script src="main.js"></script>
+            <link rel="stylesheet" href="my.css">
+
+        When you want to manipulate elements in your code, you have to
+        use domReady for your code to work properly, like this;
+
+            domReady(function(){ ... });
+        -->
+</#if>
+    <script type="text/javascript" src="./js/main.js"></script>
+    <link rel="stylesheet" type="text/css" href="./css/style.css"/>
+</head>
+
+<body>
+<#include "test_html_body.ftl">
+</body>
+</html>
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/test_html_body.ftl b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/freemarker/test_html_body.ftl
new file mode 100644 (file)
index 0000000..363eba5
--- /dev/null
@@ -0,0 +1,77 @@
+<#if TizenWebUIFW_Enable?exists>
+    <#if test_html_body_tizenwebuifw_single?exists>
+        <div data-role="page">
+            <div data-role="header" data-position="fixed">
+                <h1>Single-Page Application </h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <p>This is a single page boilerplate template that you can copy to build your first Tizen Web UI Framework page.</p>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Footer content</h4>
+            </div><!-- /footer -->
+        </div><!-- /page -->
+    <#elseif test_html_body_tizenwebuifw_multi?exists>
+        <!-- Start of first page: #one -->
+        <div data-role="page" id="one">
+            <div data-role="header" data-position="fixed">
+                <h1>Multi-Page Application</h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <h2>One</h2>
+                <p>
+                    This is a multi-page boilerplate template that you can copy to build
+                    your first Tizen Web UI Framework page. This template contains multiple "page"
+                    containers inside.
+                </p>
+                <p>
+                    You link to internal pages by referring to the ID of the page you
+                    want to show. For example, to <a href="#two">link</a> to the page
+                    with an ID of "two", my link would have a
+                    <code>href="#two"</code>
+                    in the code.
+                </p>
+                <h3>Show internal pages:</h3>
+                <p><a href="#two" data-role="button">Show page "two"</a></p>
+                <p><a href="#popup"  data-role="button" aria-haspopup="true" data-rel="popupwindow">Show page "popup" (as a dialog)</a></p>
+
+                <div id="popup" data-role="popupwindow" data-style="center_title_1btn">
+                    <p data-role="title">Popup</p>
+                    <p data-role="text">Pop-up dialog box, a child window that blocks user interact to the parent windows</p>
+                    <div data-role="button-bg"><a href="#" data-role="button" onclick="javascript:$('#popup').popupwindow('close');">Close</a></div>
+                </div>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Page Footer</h4>
+            </div><!-- /footer -->
+        </div><!-- /page one -->
+
+        <!-- Start of second page: #two -->
+        <div data-role="page" id="two">
+            <div data-role="header" data-position="fixed">
+                <h1>Two</h1>
+            </div><!-- /header -->
+
+            <div data-role="content">
+                <h2>Two</h2>
+                <p>I have an id of "two" on my page container. I'm the second
+                    page container in this multi-page template.</p>
+                <p><a href="#one" data-direction="reverse" data-role="button">Back to page "one"</a></p>
+            </div><!-- /content -->
+
+            <div data-role="footer" data-position="fixed">
+                <h4>Page Footer</h4>
+            </div><!-- /footer -->
+        </div><!-- /page two -->
+    </#if>
+<#else>
+    <header>
+    </header>
+
+    <footer>
+    </footer>
+</#if>
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/jsoup/JsoupTemplateEngineTest.java b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/jsoup/JsoupTemplateEngineTest.java
new file mode 100644 (file)
index 0000000..b395047
--- /dev/null
@@ -0,0 +1,54 @@
+package org.tizen.common.verrari.engine.jsoup;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.util.HashMap;
+
+import org.jsoup.nodes.Attribute;
+import org.jsoup.nodes.Attributes;
+import org.junit.Test;
+import org.tizen.common.verrari.model.MapModel;
+import org.tizen.common.verrari.target.TargetUnit;
+import org.tizen.common.verrari.template.FileTemplate;
+import org.tizen.common.verrari.template.ITemplate;
+
+public class JsoupTemplateEngineTest {
+
+    /**
+     * Test {@link JsoupTemplateEngine#generate(TargetUnit unit)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see JsoupTemplateEngine#generate(TargetUnit unit)
+     */
+    @Test
+    public void test_generate() throws Exception {
+        JsoupTemplateEngine engine = new JsoupTemplateEngine();
+        ITemplate template = new FileTemplate(new File("./test/src/org/tizen/common/verrari/engine/jsoup/TizenSingle.html"));
+        engine.getTemplateProvider().addTemplate("jsoupTemplate", template);
+
+        // selector - http://jsoup.org/apidocs/org/jsoup/select/Selector.html
+        MapModel mapModel = new MapModel(new HashMap<Object, Object>());
+        Attribute jquery = new Attribute("src", "/usr/share/tizen-web-ui-fw/latest/js/jquery.js");
+        mapModel.put("script[src$=tizen-web-ui-fw/latest/js/jquery.js]", jquery);
+
+        Attribute tizenwebuifwlibs = new Attribute("src", "/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js");
+        mapModel.put("script[src$=tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js]", tizenwebuifwlibs);
+
+        Attributes tizenwebuifw = new Attributes();
+        tizenwebuifw.put("src", "/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js");
+        tizenwebuifw.put("data-framework-theme", "tizen-white");
+        tizenwebuifw.put("data-framework-viewport-scale", "true");
+        mapModel.put("script[src$=tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js]", tizenwebuifw);
+
+        engine.getModelProvider().addModel("jsoupModel", mapModel);
+
+        File genTizenSingleFile = new File("./test/src/org/tizen/common/verrari/engine/jsoup/genTizenSingle.html");
+        TargetUnit unit = new TargetUnit("jsoupTemplate", "jsoupModel", new OutputStreamWriter(new FileOutputStream(genTizenSingleFile.getPath())), "UTF-8");
+        //TargetUnit unit = new TargetUnit("jsonTemplate", "jsonModel", new OutputStreamWriter(System.out), "UTF-8");
+        engine.generate(unit);
+
+    }
+
+}
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/jsoup/TizenSingle.html b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/jsoup/TizenSingle.html
new file mode 100644 (file)
index 0000000..587dae8
--- /dev/null
@@ -0,0 +1,46 @@
+<!--
+ Copyright 2012 changhyun1.lee@samsung.com All rights reserved.
+-------------------------------------------------------------------------------------------------><!DOCTYPE html>
+<html>
+ <head>
+  <meta charset="utf-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, target-densityDpi=device-dpi" />
+  <meta name="description" content="Tizen template generated by Tizen Web IDE" />
+  <title>Tizen Web UI FW - Single</title>
+  <script src="./tizen-web-ui-fw/latest/js/jquery.js"></script>
+  <script src="./tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js"></script>
+  <script src="./tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js" data-framework-theme="tizen-gray" data-framework-viewport-scale="false"></script>
+  <!--NOTE:
+        Additional scripts and css files are to be placed here.
+        You can use jQuery namespace($) and all functionalities in jQuery
+        in your script.  For example:
+
+            <script src="main.js"></script>
+            <link rel="stylesheet" href="my.css">
+
+        When you want to manipulate elements in your code, you have to
+        use domReady for your code to work properly, like this;
+
+            domReady(function(){ ... });
+        -->
+  <script type="text/javascript" src="./js/main.js"></script>
+  <link rel="stylesheet" type="text/css" href="./css/style.css" />
+ </head>
+ <body>
+  <div data-role="page">
+   <div data-role="header" data-position="fixed">
+    <h1>Single-Page Application </h1>
+   </div>
+   <!-- /header -->
+   <div data-role="content">
+    <p>This is a single page boilerplate template that you can copy to build your first Tizen Web UI Framework page.</p>
+   </div>
+   <!-- /content -->
+   <div data-role="footer" data-position="fixed">
+    <h4>Footer content</h4>
+   </div>
+   <!-- /footer -->
+  </div>
+  <!-- /page -->
+ </body>
+</html>
\ No newline at end of file
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/jsoup/genTizenSingle.html b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/engine/jsoup/genTizenSingle.html
new file mode 100644 (file)
index 0000000..79f5d74
--- /dev/null
@@ -0,0 +1,46 @@
+<!--
+ Copyright 2012 changhyun1.lee@samsung.com All rights reserved.
+-------------------------------------------------------------------------------------------------><!DOCTYPE html>
+<html>
+ <head> 
+  <meta charset="utf-8" /> 
+  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, target-densityDpi=device-dpi" /> 
+  <meta name="description" content="Tizen template generated by Tizen Web IDE" /> 
+  <title>Tizen Web UI FW - Single</title> 
+  <script src="/usr/share/tizen-web-ui-fw/latest/js/jquery.js"></script> 
+  <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js"></script> 
+  <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js" data-framework-theme="tizen-white" data-framework-viewport-scale="true"></script> 
+  <!--NOTE:
+        Additional scripts and css files are to be placed here.
+        You can use jQuery namespace($) and all functionalities in jQuery
+        in your script.  For example:
+
+            <script src="main.js"></script>
+            <link rel="stylesheet" href="my.css">
+
+        When you want to manipulate elements in your code, you have to
+        use domReady for your code to work properly, like this;
+
+            domReady(function(){ ... });
+        --> 
+  <script type="text/javascript" src="./js/main.js"></script> 
+  <link rel="stylesheet" type="text/css" href="./css/style.css" /> 
+ </head> 
+ <body> 
+  <div data-role="page"> 
+   <div data-role="header" data-position="fixed"> 
+    <h1>Single-Page Application </h1> 
+   </div> 
+   <!-- /header --> 
+   <div data-role="content"> 
+    <p>This is a single page boilerplate template that you can copy to build your first Tizen Web UI Framework page.</p> 
+   </div> 
+   <!-- /content --> 
+   <div data-role="footer" data-position="fixed"> 
+    <h4>Footer content</h4> 
+   </div> 
+   <!-- /footer --> 
+  </div> 
+  <!-- /page -->  
+ </body>
+</html>
\ No newline at end of file
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/target/TargetGruopTest.java b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/target/TargetGruopTest.java
new file mode 100644 (file)
index 0000000..73472c5
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.target;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * TargetGruopTest.
+ *
+ * Test case for {@link TargetGroup}
+ *
+ * @author Changhyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *
+ * @see TargetGroup
+ *
+ */
+public class TargetGruopTest {
+
+    protected TargetGroup group;
+
+    @Before
+    public void setUp() {
+        group = new TargetGroup();
+    }
+
+    @After
+    public void tearDown() throws IOException {
+    }
+
+    /**
+     * Test {@link TargetGroup#TargetGroup()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetGroup#TargetGroup()
+     */
+    @Test
+    public void test_TargetGroup() throws Exception {
+        assertNotNull(group.getTargetUnits());
+    }
+
+    /**
+     * Test {@link TargetGroup#getTargetUnits()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetGroup#getTargetUnits()
+     */
+    @Test
+    public void test_getTargetUnits() throws Exception {
+        assertNotNull(group.getTargetUnits());
+    }
+
+    /**
+     * Test {@link TargetGroup#addTargetUnit(TargetUnit)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetGroup#addTargetUnit(TargetUnit)
+     */
+    @Test
+    public void test_addTargetUnit() throws Exception {
+        assertFalse(group.addTargetUnit(null));
+
+        Writer writer =  null;
+        try {
+            writer = new OutputStreamWriter(System.out);
+            TargetUnit unit = new TargetUnit("templatekey", "modelkey", writer, null);
+            assertTrue(group.addTargetUnit(unit));
+        } catch (Exception e) {
+            throw e;
+        } finally {
+            if (writer != null) {
+                writer.close();
+            }
+        }
+    }
+
+    /**
+     * Test {@link TargetGroup#removeTargetunit(TargetUnit)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetGroup#removeTargetunit(TargetUnit)
+     */
+    @Test
+    public void test_removeTargetunit() throws Exception {
+        assertFalse(group.removeTargetunit(null));
+
+        Writer writer =  null;
+        try {
+            writer = new OutputStreamWriter(System.out);
+            TargetUnit unit = new TargetUnit("templatekey", "modelkey", writer, null);
+            assertTrue(group.addTargetUnit(unit));
+            assertTrue(group.removeTargetunit(unit));
+        } catch (Exception e) {
+            throw e;
+        } finally {
+            if (writer != null) {
+                writer.close();
+            }
+        }
+    }
+
+    /**
+     * Test {@link TargetGroup#isEmpty()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetGroup#isEmpty()
+     */
+    @Test
+    public void test_isEmpty() throws Exception {
+        assertTrue(group.isEmpty());
+
+        Writer writer =  null;
+        try {
+            writer = new OutputStreamWriter(System.out);
+            TargetUnit unit = new TargetUnit("templatekey", "modelkey", writer, null);
+            assertTrue(group.addTargetUnit(unit));
+            assertFalse(group.isEmpty());
+        } catch (Exception e) {
+            throw e;
+        } finally {
+            if (writer != null) {
+                writer.close();
+            }
+        }
+    }
+}
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/target/TargetUnitTest.java b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/target/TargetUnitTest.java
new file mode 100644 (file)
index 0000000..75f2d17
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.target;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * TargetUnitTest.
+ *
+ * Test case for {@link TargetUnit}
+ *
+ * @author Changhyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *
+ * @see TargetUnit
+ *
+ */
+public class TargetUnitTest {
+
+    protected TargetUnit unit;
+    protected Writer writer;
+
+    @Before
+    public void setUp() {
+        writer =  new OutputStreamWriter(System.out);
+        unit = new TargetUnit("templateKey", "modelKey", writer, "UTF-8");
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        if (writer != null) {
+            writer.close();
+        }
+    }
+
+    /**
+     * Test {@link TargetUnit#TargetUnit(String, String, Writer, String)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetUnit#TargetUnit(String, String, Writer, String)
+     */
+    @Test
+    public void test_TargetUnit() throws Exception {
+        @SuppressWarnings("unused")
+        TargetUnit tempUnit;
+
+        try {
+            tempUnit = new TargetUnit("templateKey", "modelKey", writer, null);
+        } catch (Exception e) {
+            throw e;
+        }
+
+        try {
+            tempUnit = new TargetUnit(null, null, null, null);
+            fail( "TargetUnit must throw exception" );
+        } catch (Exception e) {
+        }
+
+        try {
+            tempUnit = new TargetUnit("templateKey", "modelKey", null, null);
+            fail( "TargetUnit must throw exception" );
+        } catch (Exception e) {
+        }
+
+        try {
+            tempUnit = new TargetUnit("templateKey", null, writer, null);
+            fail( "TargetUnit must throw exception" );
+        } catch (Exception e) {
+        }
+
+        try {
+            tempUnit = new TargetUnit(null, "modelKey", writer, null);
+            fail( "TargetUnit must throw exception" );
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * Test {@link TargetUnit#setTemplateKey(String)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetUnit#setTemplateKey(String)
+     */
+    @Test
+    public void test_setTemplateKey() throws Exception {
+        unit.setTemplateKey(null);
+        assertNotNull(unit.getTemplateKey());
+
+        unit.setTemplateKey("template");
+        assertEquals(unit.getTemplateKey(), "template");
+    }
+
+    /**
+     * Test {@link TargetUnit#getTemplateKey()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetUnit#getTemplateKey()
+     */
+    @Test
+    public void test_getTemplateKey() throws Exception {
+        assertEquals(unit.getTemplateKey(), "templateKey");
+    }
+
+    /**
+     * Test {@link TargetUnit#setModelKey(String)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetUnit#setModelKey(String)
+     */
+    @Test
+    public void test_setModelKey() throws Exception {
+        unit.setModelKey(null);
+        assertNotNull(unit.getModelKey());
+
+        unit.setModelKey("model");
+        assertEquals(unit.getModelKey(), "model");
+    }
+
+    /**
+     * Test {@link TargetUnit#getModelKey()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetUnit#getModelKey()
+     */
+    @Test
+    public void test_getModelKey() throws Exception {
+        assertEquals(unit.getModelKey(), "modelKey");
+    }
+
+    /**
+     * Test {@link TargetUnit#setWriter(Writer)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetUnit#setWriter(Writer)
+     */
+    @Test
+    public void test_setWriter() throws Exception {
+        Writer tempWriter = null;
+        unit.setWriter(null);
+        assertNotNull(unit.getWriter());
+
+        try {
+            tempWriter = new OutputStreamWriter(System.out);
+            unit.setWriter(tempWriter);
+            assertEquals(unit.getWriter(), tempWriter);
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+
+    /**
+     * Test {@link TargetUnit#getWriter()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetUnit#getWriter()
+     */
+    @Test
+    public void test_getWriter() throws Exception {
+        assertEquals(writer, unit.getWriter());
+    }
+
+    /**
+     * Test {@link TargetUnit#setEncoding(String)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetUnit#setEncoding(String)
+     */
+    @Test
+    public void test_setEncoding() throws Exception {
+        unit.setEncoding(null);
+        assertNotNull(unit.getEncoding());
+
+        unit.setEncoding("UTF-8");
+        assertEquals(unit.getEncoding(), "UTF-8");
+    }
+
+    /**
+     * Test {@link TargetUnit#getEncoding()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see TargetUnit#getEncoding()
+     */
+    @Test
+    public void test_getEncoding() throws Exception {
+        assertEquals(unit.getEncoding(), "UTF-8");
+    }
+}
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/template/FileTemplateTest.java b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/template/FileTemplateTest.java
new file mode 100644 (file)
index 0000000..cfa9644
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.template;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * FileTemplateTest.
+ *
+ * Test case for {@link FileTemplate}
+ *
+ * @author Changhyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *
+ * @see FileTemplate
+ *
+ */
+public class FileTemplateTest {
+
+    protected File file;
+    protected FileTemplate fileTemplate;
+
+    @Before
+    public void setUp() {
+        file = new File("./test/src/org/tizen/common/verrari/template/test_html.ftl");
+        fileTemplate = new FileTemplate(file);
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test {@link FileTemplate#getContainer()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see FileTemplate#getContainer()
+     */
+    @Test
+    public void test_getContainer() throws Exception {
+        assertEquals(file, fileTemplate.getContainer());
+    }
+
+    /**
+     * Test {@link FileTemplate#getEncoding()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see FileTemplate#getEncoding()
+     */
+    @Test
+    public void test_getEncoding() throws Exception {
+        assertEquals(System.getProperty("file.encoding"), fileTemplate.getEncoding());
+    }
+
+    /**
+     * Test {@link FileTemplate#open()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see FileTemplate#open()
+     */
+    @Test
+    public void test_open() throws Exception {
+        //assertTrue(fileTemplate.open().);
+        String templateContents;
+        String fileConents;
+
+        BufferedReader bufferedReader = null;
+        InputStreamReader streamReader = null;
+        // get FileTemplate contents.
+        try {
+            streamReader = new InputStreamReader(fileTemplate.open(), fileTemplate.getEncoding());
+            bufferedReader = new BufferedReader(streamReader, 8192);
+            StringBuilder text = new StringBuilder();
+            final char[] buffer = new char[8192];
+            int nRead = 0;
+            while (0 < (nRead = bufferedReader.read(buffer))) {
+                text.append( buffer, 0, nRead );
+            }
+            templateContents = text.toString();
+        } catch (Exception e) {
+            throw e;
+        } finally {
+            if (streamReader != null) { streamReader.close(); }
+            if (bufferedReader != null) { bufferedReader.close(); }
+        }
+
+        // get File contents.
+        try {
+            streamReader = new InputStreamReader(new FileInputStream(file), System.getProperty("file.encoding"));
+            bufferedReader = new BufferedReader(streamReader, 8192);
+            StringBuilder text = new StringBuilder();
+            final char[] buffer = new char[8192];
+            int nRead = 0;
+            while (0 < (nRead = bufferedReader.read(buffer))) {
+                text.append( buffer, 0, nRead );
+            }
+            fileConents = text.toString();
+        } catch (Exception e) {
+            throw e;
+        } finally {
+            if (streamReader != null) { streamReader.close(); }
+            if (bufferedReader != null) { bufferedReader.close(); }
+        }
+
+        assertEquals(templateContents, fileConents);
+    }
+
+}
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/template/StaticTemplateProviderTest.java b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/template/StaticTemplateProviderTest.java
new file mode 100644 (file)
index 0000000..7f4268f
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Verrari - TemplateEngine
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 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.common.verrari.template;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.net.URI;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * StaticTemplateProviderTest.
+ *
+ * Test case for {@link StaticTemplateProvider}
+ *
+ * @author Changhyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *
+ * @see StaticTemplateProvider
+ *
+ */
+public class StaticTemplateProviderTest {
+
+    protected StaticTemplateProvider stp;
+
+    @Before
+    public void setUp() {
+        stp = new StaticTemplateProvider();
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test {@link StaticTemplateProvider#addTemplate(String, ITemplate)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see StaticTemplateProvider#addTemplate(String, ITemplate)
+     */
+    @Test
+    public void test_addTemplate() throws Exception {
+        assertTrue(stp.isEmpty());
+        FileTemplate fileTemplate = new FileTemplate(new File("./test/src/org/tizen/common/verrari/template/test_html.ftl"));
+        stp.addTemplate("testhtml", fileTemplate);
+        assertFalse(stp.isEmpty());
+        assertNotNull(stp.getTemplate("testhtml"));
+    }
+
+    /**
+     * Test {@link StaticTemplateProvider#addTemplate(String, URI)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see StaticTemplateProvider#addTemplate(String, URI)
+     */
+    @Test
+    public void test_addTemplate2() throws Exception {
+        assertTrue(stp.isEmpty());
+        File file = new File("./test/src/org/tizen/common/verrari/template/test_html.ftl");
+        URI uri = file.toURI();
+        stp.addTemplate("testhtml", uri);
+        assertFalse(stp.isEmpty());
+        assertNotNull(stp.getTemplate("testhtml"));
+    }
+
+    /**
+     * Test {@link StaticTemplateProvider#addTemplate(String, File)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see StaticTemplateProvider#addTemplate(String, File)
+     */
+    @Test
+    public void test_addTemplate3() throws Exception {
+        assertTrue(stp.isEmpty());
+        stp.addTemplate("testhtml", new File("./test/src/org/tizen/common/verrari/template/test_html.ftl"));
+        assertFalse(stp.isEmpty());
+        assertNotNull(stp.getTemplate("testhtml"));
+    }
+
+    /**
+     * Test {@link StaticTemplateProvider#getTemplate()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see StaticTemplateProvider#getTemplate()
+     */
+    @Test
+    public void test_getTemplate() throws Exception {
+        assertTrue(stp.isEmpty());
+        stp.addTemplate("testhtml", new File("./test/src/org/tizen/common/verrari/template/test_html.ftl"));
+        assertNotNull(stp.getTemplate("testhtml"));
+    }
+
+    /**
+     * Test {@link StaticTemplateProvider#removeTemplate(String)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see StaticTemplateProvider#removeTemplate(String)
+     */
+    @Test
+    public void test_removeTemplate() throws Exception {
+        assertTrue(stp.isEmpty());
+        stp.addTemplate("testhtml", new File("./test/src/org/tizen/common/verrari/template/test_html.ftl"));
+        assertFalse(stp.isEmpty());
+        stp.removeTemplate(null);
+        assertFalse(stp.isEmpty());
+        stp.removeTemplate("testhtml");
+        assertTrue(stp.isEmpty());
+    }
+
+    /**
+     * Test {@link StaticTemplateProvider#getTemplates()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see StaticTemplateProvider#getTemplates()
+     */
+    @Test
+    public void test_getTemplates() throws Exception {
+        assertTrue(stp.isEmpty());
+        stp.addTemplate("testhtml", new File("./test/src/org/tizen/common/verrari/template/test_html.ftl"));
+        assertFalse(stp.isEmpty());
+
+        Map<String, ITemplate> templates = stp.getTemplates();
+        assertFalse(templates.isEmpty());
+        assertEquals(stp.getTemplate("testhtml"), templates.get("testhtml"));
+    }
+
+    /**
+     * Test {@link StaticTemplateProvider#isEmpty()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see StaticTemplateProvider#isEmpty()
+     */
+    @Test
+    public void test_isEmpty() throws Exception {
+        assertTrue(stp.isEmpty());
+        stp.addTemplate("testhtml", new File("./test/src/org/tizen/common/verrari/template/test_html.ftl"));
+        assertFalse(stp.isEmpty());
+        stp.removeTemplate("testhtml");
+        assertTrue(stp.isEmpty());
+    }
+
+}
diff --git a/org.tizen.common.verrari/test/src/org/tizen/common/verrari/template/test_html.ftl b/org.tizen.common.verrari/test/src/org/tizen/common/verrari/template/test_html.ftl
new file mode 100644 (file)
index 0000000..00ed030
--- /dev/null
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title> ${test_html!'defaultName'} </title>
+</head>
+
+<body>
+</body>
+</html>
old mode 100644 (file)
new mode 100755 (executable)
index c619f68..8e01f7b
@@ -1,8 +1,22 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-       <classpathentry exported="true" kind="lib" path="sdblib.jar"/>
-       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
-       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-       <classpathentry kind="src" path="src"/>
-       <classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry exported="true" kind="lib" path="lib/commons-logging-1.1.1.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/commons-collections-3.2.1.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/commons-pool-1.6.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/commons-lang3-3.1.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/commons-io-2.4.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/freemarker.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/log4j-1.2.17.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/sdblib.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/slf4j-api-1.6.4.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="lib/slf4j-log4j12-1.6.4.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="test/lib/junit-4.10.jar" sourcepath="test/lib/junit-4.10-src.jar"/>\r
+       <classpathentry exported="true" kind="lib" path="test/lib/mockito-all-1.9.0.jar"/>\r
+       <classpathentry kind="lib" path="test/lib/asm-4.0.jar"/>\r
+       <classpathentry kind="lib" path="test/lib/asm-tree-4.0.jar"/>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="src" path="test/src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/org.tizen.common/.settings/org.eclipse.core.resources.prefs b/org.tizen.common/.settings/org.eclipse.core.resources.prefs
new file mode 100644 (file)
index 0000000..05557ba
--- /dev/null
@@ -0,0 +1,3 @@
+#Tue Jun 05 12:49:09 KST 2012
+eclipse.preferences.version=1
+encoding/<project>=utf-8
old mode 100644 (file)
new mode 100755 (executable)
index 70adb4a..39657a9
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: Tizen Common
+Bundle-Name: %Bundle-Name
 Bundle-SymbolicName: org.tizen.common;singleton:=true
 Bundle-Version: 1.0.0.qualifier
-Bundle-Vendor: Samsung
+Bundle-Vendor: %Bundle-Vendor
 Require-Bundle: org.eclipse.ui,
  org.eclipse.core.runtime,
  org.eclipse.ui.ide,
  org.eclipse.core.resources,
  org.eclipse.core.filesystem
 Export-Package: 
- org.tizen.sdblib,
- org.tizen.common.cache,
- org.tizen.common.console,
- org.tizen.common.control,
- org.tizen.common.log,
- org.tizen.common.manager,
- org.tizen.common.model,
- org.tizen.common.properties,
- org.tizen.common.swt,
- org.tizen.common.util
+ freemarker.ext.dom,
+ freemarker.template,
+ org.apache.commons.lang3,
+ org.apache.commons.lang3.builder,
+ org.apache.commons.lang3.concurrent,
+ org.apache.commons.lang3.event,
+ org.apache.commons.lang3.exception,
+ org.apache.commons.lang3.math,
+ org.apache.commons.lang3.mutable,
+ org.apache.commons.lang3.reflect,
+ org.apache.commons.lang3.text,
+ org.apache.commons.lang3.text.translate,
+ org.apache.commons.lang3.time,
+ org.apache.commons.lang3.tuple,
+ org.apache.commons.logging,
+ org.junit,
+ org.junit.experimental,
+ org.junit.experimental.categories,
+ org.junit.experimental.max,
+ org.junit.experimental.results,
+ org.junit.experimental.runners,
+ org.junit.experimental.theories,
+ org.junit.experimental.theories.internal,
+ org.junit.experimental.theories.suppliers,
+ org.junit.internal,
+ org.junit.internal.builders,
+ org.junit.internal.matchers,
+ org.junit.internal.requests,
+ org.junit.internal.runners,
+ org.junit.internal.runners.model,
+ org.junit.internal.runners.rules,
+ org.junit.internal.runners.statements,
+ org.junit.matchers,
+ org.junit.rules,
+ org.junit.runner,
+ org.junit.runner.manipulation,
+ org.junit.runner.notification,
+ org.junit.runners,
+ org.junit.runners.model,
+ org.mockito,
+ org.mockito.asm,
+ org.mockito.asm.signature,
+ org.mockito.asm.tree,
+ org.mockito.asm.tree.analysis,
+ org.mockito.asm.util,
+ org.mockito.cglib.beans,
+ org.mockito.cglib.core,
+ org.mockito.cglib.proxy,
+ org.mockito.cglib.reflect,
+ org.mockito.cglib.transform,
+ org.mockito.cglib.transform.impl,
+ org.mockito.cglib.util,
+ org.mockito.configuration,
+ org.mockito.exceptions,
+ org.mockito.exceptions.base,
+ org.mockito.exceptions.misusing,
+ org.mockito.exceptions.verification,
+ org.mockito.exceptions.verification.junit,
+ org.mockito.internal,
+ org.mockito.internal.configuration,
+ org.mockito.internal.configuration.injection,
+ org.mockito.internal.configuration.injection.filter,
+ org.mockito.internal.creation,
+ org.mockito.internal.creation.cglib,
+ org.mockito.internal.creation.jmock,
+ org.mockito.internal.debugging,
+ org.mockito.internal.exceptions,
+ org.mockito.internal.exceptions.base,
+ org.mockito.internal.exceptions.util,
+ org.mockito.internal.invocation,
+ org.mockito.internal.invocation.finder,
+ org.mockito.internal.invocation.realmethod,
+ org.mockito.internal.listeners,
+ org.mockito.internal.matchers,
+ org.mockito.internal.matchers.apachecommons,
+ org.mockito.internal.progress,
+ org.mockito.internal.reporting,
+ org.mockito.internal.runners,
+ org.mockito.internal.runners.util,
+ org.mockito.internal.stubbing,
+ org.mockito.internal.stubbing.answers,
+ org.mockito.internal.stubbing.defaultanswers,
+ org.mockito.internal.util,
+ org.mockito.internal.util.junit,
+ org.mockito.internal.util.reflection,
+ org.mockito.internal.verification,
+ org.mockito.internal.verification.api,
+ org.mockito.internal.verification.argumentmatching,
+ org.mockito.internal.verification.checkers,
+ org.mockito.invocation,
+ org.mockito.listeners,
+ org.mockito.runners,
+ org.mockito.stubbing,
+ org.mockito.stubbing.answers,
+ org.mockito.verification,
+ org.slf4j,
+ org.tizen.common,
+ org.tizen.common.core.application,
+ org.tizen.common.core.command,
+ org.tizen.common.core.command.file,
+ org.tizen.common.core.command.policy,
+ org.tizen.common.core.command.prompter,
+ org.tizen.common.core.command.sdb,
+ org.tizen.common.core.command.zip,
+ org.tizen.common.file,
+ org.tizen.common.file.filter,
+ org.tizen.common.ui,
+ org.tizen.common.ui.dialog,
+ org.tizen.common.ui.page.preference,
+ org.tizen.common.ui.page.wizard,
+ org.tizen.common.ui.view.console,
+ org.tizen.common.ui.widget,
+ org.tizen.common.util,
+ org.tizen.common.util.cache,
+ org.tizen.common.util.log,
+ org.tizen.common.util.url.classpath,
+ org.tizen.common.util.url.cp,
+ org.tizen.common.util.url.vf,
+ org.tizen.sdblib
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Import-Package: 
  org.eclipse.jface.text,
  org.eclipse.ui.console
 Bundle-Activator: org.tizen.common.CommonPlugin
 Bundle-ActivationPolicy: lazy
-Bundle-ClassPath: sdblib.jar,
- .
+Bundle-ClassPath: .,
+ lib/log4j-1.2.17.jar,
+ lib/sdblib.jar,
+ lib/slf4j-api-1.6.4.jar,
+ lib/slf4j-log4j12-1.6.4.jar,
+ lib/freemarker.jar,
+ lib/commons-io-2.4.jar,
+ lib/commons-lang3-3.1.jar,
+ lib/commons-collections-3.2.1.jar,
+ lib/commons-pool-1.6.jar,
+ lib/commons-logging-1.1.1.jar
index 99ec9ad..c4bd08c 100644 (file)
@@ -1,3 +1,26 @@
+Bundle-Vendor = Samsung Electronics
+
 activity.name = newXsdDisabler
 activity.name.0 = newDtdDisabler
-activity.name.1 = ValidateMenuItemDisabler
\ No newline at end of file
+activity.name.1 = ValidateMenuItemDisabler
+
+category.name = Tizen
+page.name = Tizen SDK
+activity.description = Popup UI
+activity.name.2 = Popup UI
+category.description = Disable CDT launch UI when Native App Perspective is activated.
+category.name.0 = CDT launch UI
+activity.description.0 = Launch UI elements from CDT
+activity.name.3 = CDT Launch UI Elements
+category.description.0 = Disable CDT Toolchain Editor Page when Tizen Perspective is activated.
+category.name.1 = CDT ToolChain Editor Page
+activity.description.1 = ToolChain Editor Property Page
+activity.name.4 = CDT ToolChain Editor Page Elements
+activity.description.2 = Wizard UI
+activity.name.5 = Wizard UI
+activity.description.3 = PopupMenus
+activity.name.6 = PopupMenus
+category.name.2 = Tizen
+category.name.3 = Tizen
+extension-point.name = Prompter
+Bundle-Name = Tizen Common
\ No newline at end of file
index 95bb5ff..d713227 100644 (file)
@@ -37,5 +37,17 @@ A copy of the license is included in <a href="about_files/epl-v10.html">about_fi
 </ul>
 </p>
 
+<h4>FreeMarker</h4>
+<p>
+FreeMarker is a "template engine"; a generic tool to generate text output (anything from HTML to autogenerated source code) based on templates. It's a Java package, a class library for Java programmers. It's not an application for end-users in itself, but something that programmers can embed into their products.
+</p>
+
+<p>
+A copy of the license is included in <a href="about_files/freemarker-LICENSE.txt">about_files/freemarker-LICENSE.txt</a>. The home page is located at:
+<ul>
+<a href="http://freemarker.sourceforge.net/">http://freemarker.sourceforge.net/</a>
+</ul>
+</p>
+
 </body>
 </html>
\ No newline at end of file
diff --git a/org.tizen.common/about_files/freemarker-LICENSE.txt b/org.tizen.common/about_files/freemarker-LICENSE.txt
new file mode 100644 (file)
index 0000000..4c5f086
--- /dev/null
@@ -0,0 +1,69 @@
+FreeMarker 1.x was released under the LGPL license. Later, by community\r
+consensus, we have switched over to a BSD-style license. As of FreeMarker\r
+2.2pre1, the original author, Benjamin Geer, has relinquished the copyright in\r
+behalf of Visigoth Software Society. The current copyright holder is the\r
+Visigoth Software Society.\r
+\r
+------------------------------------------------------------------------------\r
+Copyright (c) 2003 The Visigoth Software Society. All rights reserved.\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are met:\r
+\r
+1.  Redistributions of source code must retain the above copyright notice,\r
+    this list of conditions and the following disclaimer.\r
+\r
+2.  The end-user documentation included with the redistribution, if any, must\r
+    include the following acknowlegement:\r
+      "This product includes software developed by the \r
+      Visigoth Software Society (http://www.visigoths.org/)."\r
+    Alternately, this acknowlegement may appear in the software itself, if and\r
+    wherever such third-party acknowlegements normally appear.\r
+\r
+3.  Neither the name "FreeMarker", "Visigoth", nor any of the names of the\r
+    project contributors may be used to endorse or promote products derived\r
+    from this software without prior written permission. For written\r
+    permission, please contact visigoths@visigoths.org.\r
+\r
+4.  Products derived from this software may not be called "FreeMarker" or\r
+    "Visigoth" nor may "FreeMarker" or "Visigoth" appear in their names\r
+    without prior written permission of the Visigoth Software Society.\r
+\r
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+VISIGOTH SOFTWARE SOCIETY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\r
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+------------------------------------------------------------------------------\r
+\r
+This software consists of voluntary contributions made by many individuals on\r
+behalf of the Visigoth Software Society. For more information on the Visigoth\r
+Software Society, please see http://www.visigoths.org/\r
+\r
+------------------------------------------------------------------------------\r
+\r
+FREEMARKER SUBCOMPONENTS UNDER DIFFERENT LICENSE:\r
+\r
+FreeMarker includes a number of subcomponents that are licensed by the Apache\r
+Software Foundation under the Apache License, Version 2.0. Your use of these\r
+subcomponents is subject to the terms and conditions of the Apache License,\r
+Version 2.0. You may obtain a copy of the License at\r
+\r
+    http://www.apache.org/licenses/LICENSE-2.0\r
+    \r
+The subcomponents under this licence are the following files, which are\r
+included both in freemarker.jar and in the source code:\r
+  \r
+    freemarker/ext/jsp/web-app_2_2.dtd\r
+    freemarker/ext/jsp/web-app_2_3.dtd\r
+    freemarker/ext/jsp/web-app_2_4.xsd\r
+    freemarker/ext/jsp/web-app_2_5.xsd\r
+    freemarker/ext/jsp/web-jsptaglibrary_1_1.dtd\r
+    freemarker/ext/jsp/web-jsptaglibrary_1_2.dtd\r
+    freemarker/ext/jsp/web-jsptaglibrary_2_0.xsd\r
+    freemarker/ext/jsp/web-jsptaglibrary_2_1.xsd\r
old mode 100644 (file)
new mode 100755 (executable)
index 889acff..49d1a30
@@ -3,9 +3,16 @@ output.. = bin/
 bin.includes = META-INF/,\\r
                .,\\r
                icons/,\\r
-               sdblib.jar,\\r
                about.html,\\r
                about_files/,\\r
-               plugin.xml\r
+               plugin.xml,\\r
+               lib/,\\r
+               lib/commons-io-2.4.jar,\\r
+               lib/commons-lang3-3.1.jar,\\r
+               lib/commons-collections-3.2.1.jar,\\r
+               lib/commons-pool-1.6.jar,\\r
+               OSGI-INF/,\\r
+               OSGI-INF/l10n/bundle.properties,\\r
+               lib/commons-logging-1.1.1.jar\r
 javacSource = 1.6
 javacTarget = 1.6
diff --git a/org.tizen.common/icons/back.gif b/org.tizen.common/icons/back.gif
new file mode 100644 (file)
index 0000000..4fb4150
Binary files /dev/null and b/org.tizen.common/icons/back.gif differ
diff --git a/org.tizen.common/icons/forward.gif b/org.tizen.common/icons/forward.gif
new file mode 100644 (file)
index 0000000..e2f8c3e
Binary files /dev/null and b/org.tizen.common/icons/forward.gif differ
diff --git a/org.tizen.common/lib/commons-collections-3.2.1.jar b/org.tizen.common/lib/commons-collections-3.2.1.jar
new file mode 100644 (file)
index 0000000..c35fa1f
Binary files /dev/null and b/org.tizen.common/lib/commons-collections-3.2.1.jar differ
diff --git a/org.tizen.common/lib/commons-io-2.4.jar b/org.tizen.common/lib/commons-io-2.4.jar
new file mode 100644 (file)
index 0000000..90035a4
Binary files /dev/null and b/org.tizen.common/lib/commons-io-2.4.jar differ
diff --git a/org.tizen.common/lib/commons-lang3-3.1.jar b/org.tizen.common/lib/commons-lang3-3.1.jar
new file mode 100644 (file)
index 0000000..a85e539
Binary files /dev/null and b/org.tizen.common/lib/commons-lang3-3.1.jar differ
diff --git a/org.tizen.common/lib/commons-logging-1.1.1.jar b/org.tizen.common/lib/commons-logging-1.1.1.jar
new file mode 100644 (file)
index 0000000..1deef14
Binary files /dev/null and b/org.tizen.common/lib/commons-logging-1.1.1.jar differ
diff --git a/org.tizen.common/lib/commons-pool-1.6.jar b/org.tizen.common/lib/commons-pool-1.6.jar
new file mode 100644 (file)
index 0000000..72ca75a
Binary files /dev/null and b/org.tizen.common/lib/commons-pool-1.6.jar differ
diff --git a/org.tizen.common/lib/freemarker.jar b/org.tizen.common/lib/freemarker.jar
new file mode 100644 (file)
index 0000000..b3673e2
Binary files /dev/null and b/org.tizen.common/lib/freemarker.jar differ
diff --git a/org.tizen.common/lib/log4j-1.2.17.jar b/org.tizen.common/lib/log4j-1.2.17.jar
new file mode 100644 (file)
index 0000000..068867e
Binary files /dev/null and b/org.tizen.common/lib/log4j-1.2.17.jar differ
diff --git a/org.tizen.common/lib/sdblib.jar b/org.tizen.common/lib/sdblib.jar
new file mode 100644 (file)
index 0000000..dc30369
Binary files /dev/null and b/org.tizen.common/lib/sdblib.jar differ
diff --git a/org.tizen.common/lib/slf4j-api-1.6.4.jar b/org.tizen.common/lib/slf4j-api-1.6.4.jar
new file mode 100644 (file)
index 0000000..4d23f41
Binary files /dev/null and b/org.tizen.common/lib/slf4j-api-1.6.4.jar differ
diff --git a/org.tizen.common/lib/slf4j-log4j12-1.6.4.jar b/org.tizen.common/lib/slf4j-log4j12-1.6.4.jar
new file mode 100644 (file)
index 0000000..daa3aa1
Binary files /dev/null and b/org.tizen.common/lib/slf4j-log4j12-1.6.4.jar differ
index 8deffd8..1f584bf 100644 (file)
@@ -1,25 +1,41 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 <?eclipse version="3.4"?>\r
 <plugin>\r
+    <extension-point id="org.tizen.common.prompter" name="%extension-point.name" schema="schema/org.tizen.common.prompter.exsd"/>\r
+    <extension\r
+        point="org.eclipse.ui.bindings">\r
+        <key\r
+            commandId="org.eclipse.ui.project.buildProject"\r
+            contextId="org.eclipse.ui.contexts.window"\r
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"\r
+            sequence="F10">\r
+        </key>\r
+        <key\r
+            commandId="org.eclipse.ui.project.buildProject"\r
+            contextId="org.eclipse.ui.contexts.window"\r
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"\r
+            sequence="M1+M2+F10">\r
+        </key>\r
+    </extension>\r
     <extension\r
         point="org.eclipse.ui.newWizards">\r
         <category\r
             id="org.tizen.nativeapp.newCategory"\r
-            name="Tizen">\r
+            name="%category.name">\r
         </category>\r
     </extension>\r
     <extension\r
         point="org.eclipse.ui.preferencePages">\r
         <page\r
-            class="org.tizen.common.preferences.TizenBasePreferencePage"\r
+            class="org.tizen.common.ui.page.preference.TizenBasePreferencePage"\r
             id="org.tizen.common.preferences.tizencommon"\r
-            name="Tizen SDK">\r
+            name="%page.name">\r
         </page>\r
     </extension>\r
     <extension\r
         point="org.eclipse.ui.startup">\r
         <startup\r
-            class="org.tizen.common.update.UpdateManager">\r
+            class="org.tizen.common.core.application.UpdateManager">\r
         </startup>\r
     </extension>\r
     <!-- activities start -->\r
         point="org.eclipse.ui.activities">\r
         <!-- disable rhino lauch shortcuts & wst launch shortcut -->\r
         <activity\r
-            name="Popup UI"\r
-            description="Popup UI"\r
+            name="%activity.name.2"\r
+            description="%activity.description"\r
             id="org.tizen.web.launch.DisablePopupMenu">\r
         <enabledWhen>\r
             <with variable="activeWorkbenchWindow.activePerspective">\r
                 <and>\r
                     <not>\r
-                        <equals value="org.tizen.web.ui.perspective.WACwidget"/>\r
+                        <equals value="org.tizen.web.ui.perspective.WebWidget"/>\r
                     </not>\r
                     <not>\r
                         <equals value="org.tizen.nativeapp.perspective"/>\r
                     </not>\r
+                    <not>\r
+                        <equals value="org.tizen.webguibuilder.BuilderPerspective"/>\r
+                    </not>\r
                 </and>\r
             </with>\r
         </enabledWhen>\r
         point="org.eclipse.ui.activities">\r
         <!-- disable CDT launch ui -->\r
         <category\r
-            name="CDT launch UI"\r
-            description="Disable CDT launch UI when Native App Perspective is activated."\r
+            name="%category.name.0"\r
+            description="%category.description"\r
             id="org.tizen.nativeapp.CDTLaunchUICategory">\r
          </category>\r
 \r
         <activity\r
-            name="CDT Launch UI Elements"\r
-            description="Launch UI elements from CDT"\r
+            name="%activity.name.3"\r
+            description="%activity.description.0"\r
             id="org.tizen.nativeapp.DisableCDTLaunchUIActivity">\r
 \r
             <enabledWhen>\r
                 <with variable="activeWorkbenchWindow.activePerspective">\r
                     <and>\r
                         <not>\r
-                            <equals value="org.tizen.web.ui.perspective.WACwidget"/>\r
+                            <equals value="org.tizen.web.ui.perspective.WebWidget"/>\r
                         </not>\r
                         <not>\r
                             <equals value="org.tizen.nativeapp.perspective"/>\r
                         </not>\r
+                        <not>\r
+                            <equals value="org.tizen.webguibuilder.BuilderPerspective"/>\r
+                        </not>\r
                     </and>\r
                 </with>\r
             </enabledWhen>\r
 \r
         <!-- disable CDT toolchain editor page -->\r
         <category\r
-              description="Disable CDT Toolchain Editor Page when Tizen Perspective is activated."\r
+              description="%category.description.0"\r
               id="org.tizen.nativeapp.CDTToolChainEditorPageCategory"\r
-              name="CDT ToolChain Editor Page">\r
+              name="%category.name.1">\r
         </category>\r
         <activity\r
-              description="ToolChain Editor Property Page"\r
+              description="%activity.description.1"\r
               id="org.tizen.nativeapp.DisableCDTToolChainEditorPageActivity"\r
-              name="CDT ToolChain Editor Page Elements">\r
+              name="%activity.name.4">\r
             <enabledWhen>\r
                 <with variable="activeWorkbenchWindow.activePerspective">\r
                     <and>\r
                         <not>\r
-                            <equals value="org.tizen.web.ui.perspective.WACwidget"/>\r
+                            <equals value="org.tizen.web.ui.perspective.WebWidget"/>\r
                         </not>\r
                         <not>\r
                             <equals value="org.tizen.nativeapp.perspective"/>\r
                         </not>\r
+                        <not>\r
+                            <equals value="org.tizen.webguibuilder.BuilderPerspective"/>\r
+                        </not>\r
                     </and>\r
                 </with>\r
             </enabledWhen>\r
 \r
 \r
         <activity\r
-            name="Wizard UI"\r
-            description="Wizard UI"\r
+            name="%activity.name.5"\r
+            description="%activity.description.2"\r
             id="org.tizen.web.DisableWizardsActivity">\r
             <enabledWhen>\r
                 <with variable="activeWorkbenchWindow.activePerspective">\r
                     <and>\r
                         <not>\r
-                            <equals value="org.tizen.web.ui.perspective.WACwidget"/>\r
+                            <equals value="org.tizen.web.ui.perspective.WebWidget"/>\r
                         </not>\r
                         <not>\r
                             <equals value="org.tizen.nativeapp.perspective"/>\r
                         </not>\r
+                        <not>\r
+                            <equals value="org.tizen.webguibuilder.BuilderPerspective"/>\r
+                        </not>\r
                     </and>\r
                 </with>\r
             </enabledWhen>\r
         </activity>\r
         <activityPatternBinding\r
             activityId="org.tizen.web.DisableWizardsActivity"\r
-            pattern="com\.samsung\.tizen\.guibuilder/com\.samsung\.tizen\.guibuilder\.wizard\.newSgmWizard">\r
-        </activityPatternBinding>\r
-        <activityPatternBinding\r
-            activityId="org.tizen.web.DisableWizardsActivity"\r
             pattern="org\.eclipse\.jdt\.ui/org\.eclipse\.jdt\.ui\.wizards\.JavaProjectWizard">\r
         </activityPatternBinding>\r
         <activityPatternBinding\r
             activityId="org.tizen.web.DisableWizardsActivity"\r
             pattern="org\.eclipse\.wst\.dtd\.ui/org\.eclipse\.wst\.dtd\.ui\.internal\.wizard\.NewDTDWizard">\r
         </activityPatternBinding>\r
-        <activityPatternBinding\r
+        <!-- JSON File Wizard -->\r
+        <!-- activityPatternBinding\r
             activityId="org.tizen.web.DisableWizardsActivity"\r
             pattern="json\.editor\.plugin/Json\.newFileWizard">\r
-        </activityPatternBinding>\r
+        </activityPatternBinding-->\r
         <activityPatternBinding\r
             activityId="org.tizen.web.DisableWizardsActivity"\r
             pattern="org\.eclipse\.wst\.xml\.ui/org\.eclipse\.wst\.xml\.ui\.internal\.wizards\.NewXMLWizard">\r
         point="org.eclipse.ui.activities">\r
         <!-- PopupMenus Enabled when tizen Web IDE perspective -->\r
         <activity\r
-            description="PopupMenus"\r
+            description="%activity.description.3"\r
             id="org.tizen.web.PopupMenusActivity"\r
-            name="PopupMenus">\r
+            name="%activity.name.6">\r
             <enabledWhen>\r
+                <and>\r
                 <with\r
                     variable="activeWorkbenchWindow.activePerspective">\r
                     <and>\r
                         <equals\r
-                            value="org.tizen.web.ui.perspective.WACwidget">\r
+                            value="org.tizen.web.ui.perspective.WebWidget">\r
                         </equals>\r
                     </and>\r
                 </with>\r
+                <with variable="selection">\r
+                    <iterate ifEmpty="false">\r
+                        <test property="org.eclipse.core.resources.projectNature"\r
+                                value="org.tizen.web.project.builder.WebNature" />\r
+                    </iterate>\r
+                </with>\r
+                </and>\r
             </enabledWhen>\r
         </activity>\r
         <activityPatternBinding\r
              pattern="org.tizen.web.localization/org.tizen.web.localization.menus.popup.localizationMenu">\r
        </activityPatternBinding>\r
     </extension>\r
+    <extension\r
+          point="org.eclipse.ui.importWizards">\r
+       <category\r
+             id="org.tizen.nativeapp.importCategory"\r
+             name="%category.name.2">\r
+       </category>\r
+    </extension>\r
+    <extension\r
+          point="org.eclipse.ui.exportWizards">\r
+       <category\r
+             id="org.tizen.nativeapp.exportCategory"\r
+             name="%category.name.3">\r
+       </category>\r
+    </extension>\r
     <!-- activities end -->\r
 </plugin>
diff --git a/org.tizen.common/schema/org.tizen.common.prompter.exsd b/org.tizen.common/schema/org.tizen.common.prompter.exsd
new file mode 100644 (file)
index 0000000..cb67108
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.tizen.common" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.tizen.common" id="org.tizen.common.prompter" name="Prompter"/>
+      </appinfo>
+      <documentation>
+         [Enter description of this extension point.]
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <choice minOccurs="1" maxOccurs="unbounded">
+            <element ref="prompter"/>
+         </choice>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="prompter">
+      <complexType>
+         <attribute name="scope" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.tizen.common.core.command.Prompter"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+
+</schema>
diff --git a/org.tizen.common/sdblib.jar b/org.tizen.common/sdblib.jar
deleted file mode 100644 (file)
index 28a8a04..0000000
Binary files a/org.tizen.common/sdblib.jar and /dev/null differ
diff --git a/org.tizen.common/src/org/tizen/common/Adaptable.java b/org.tizen.common/src/org/tizen/common/Adaptable.java
new file mode 100644 (file)
index 0000000..8fb8935
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Common
+ *
+ * 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.common;
+
+/**
+ * <p>
+ * Adaptable.
+ * 
+ * Class for adapter pattern
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface
+Adaptable
+{
+       /**
+        * Adapt to new type interface or class
+        * 
+        * @param <T> new type
+        * @param clazz new type class
+        * 
+        * @return object to adapt to
+        */
+       public <T> T adapt( Class<T> clazz );
+}
diff --git a/org.tizen.common/src/org/tizen/common/AppIdGenerator.java b/org.tizen.common/src/org/tizen/common/AppIdGenerator.java
new file mode 100644 (file)
index 0000000..1712b04
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@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.common;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Appid generator.
+ * It is consist of 0-9, a-z
+ */
+public class AppIdGenerator {
+    final char[] PSEUDO_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7',
+            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
+            'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+            'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
+            'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+            'y', 'z' };
+
+    final BigInteger PSEUDO_CHAR_SIZE = new BigInteger("62");
+
+    // Reserved AppID (or prefix)
+    static final String RESERVED_APPID [] = {
+                                            "TIZEN",
+                                            "PRIVT",
+                                            "WIDGT"
+                                            };
+    // Number of reserved AppID
+    static final int RESERVED_APPID_NUMBER = 3;
+
+    private String convertBytesToAlphaNumeric(byte in[], int size) {
+        BigInteger randomBigInt = new BigInteger(in).abs();
+        StringBuffer out = new StringBuffer(size + 1);
+
+        for (int i = 0; i < size; ++i) {
+            BigInteger[] dividedAndremainder = randomBigInt.divideAndRemainder(PSEUDO_CHAR_SIZE);
+            randomBigInt = dividedAndremainder[0];
+            out.append(PSEUDO_CHARS[dividedAndremainder[1].intValue()]);
+        }
+
+        String ret = new String(out);
+        return ret;
+    }
+
+    private byte[] generateRandomBytes(int size) throws Exception {
+        SecureRandom random = new SecureRandom();
+        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+        keyGen.init(128);
+
+        byte[] bytes = new byte[size];
+        random.nextBytes(bytes);
+
+        SecretKey secretkey = keyGen.generateKey();
+        byte[] key = secretkey.getEncoded();
+        SecretKeySpec secretkeySpec = new SecretKeySpec(key, "AES");
+
+        Cipher cipher = Cipher.getInstance("AES");
+        cipher.init(Cipher.ENCRYPT_MODE, secretkeySpec);
+
+        return cipher.doFinal(bytes);
+    }
+
+    private boolean check(String appId) {
+        for (int i = 0; i < RESERVED_APPID_NUMBER; ++ i) {
+            if (appId.indexOf(RESERVED_APPID[i]) == 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Generate an id of length n.
+     *
+     * @param size id length
+     * @return id
+     */
+    public String generate(int size) throws Exception {
+        String appId = "";
+        do {
+            appId = convertBytesToAlphaNumeric(generateRandomBytes(size), size);
+        } while (!check(appId));
+
+        return appId;
+    }
+
+    /**
+     * Generate an id of length 10.
+     *
+     * @return id
+     */
+    public String generate() throws Exception {
+        return generate(10);
+    }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/Cabinet.java b/org.tizen.common/src/org/tizen/common/Cabinet.java
new file mode 100755 (executable)
index 0000000..5ed46d0
--- /dev/null
@@ -0,0 +1,10 @@
+package org.tizen.common;\r
+\r
+public interface\r
+Cabinet<T>\r
+extends Runnable\r
+{\r
+    public T getData();\r
+    \r
+    public void setData( T data );\r
+}\r
index b337172..736d1d7 100644 (file)
@@ -3,10 +3,10 @@
 *
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
 *
-* Contact: 
+* Contact:
 * Changhyun Lee <changhyun1.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
 */
 package org.tizen.common;
 
-import java.io.File;
-
+import org.apache.log4j.spi.RepositorySelector;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
-import org.tizen.common.preferences.TizenBasePreferencePage;
-import org.tizen.common.properties.InstallPathConfig;
+import org.tizen.common.core.application.InstallPathConfig;
+import org.tizen.common.core.command.EclipseExecutor;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.core.command.Prompter;
+import org.tizen.common.core.command.prompter.EclipsePrompter;
+import org.tizen.common.core.command.prompter.SWTPrompter;
+import org.tizen.common.ui.page.preference.TizenBasePreferencePage;
+import org.tizen.common.util.DialogUtil;
 import org.tizen.common.util.HostUtil;
 import org.tizen.common.util.OSChecker;
-
+import org.tizen.common.util.log.Logger;
 import org.tizen.sdblib.SmartDevelopmentBridge;
 
 /**
@@ -45,36 +50,69 @@ public class CommonPlugin extends AbstractUIPlugin {
 
     // The plug-in ID
     public static final String PLUGIN_ID = "org.tizen.common"; //$NON-NLS-1$
-    private final static String SDKSUFFIX = File.separatorChar+".TizenSDK"+File.separatorChar+"tizensdkpath";
     // The shared instance
     private static CommonPlugin plugin;
-
+    
     /**
-     * The constructor
+     * {@link Prompter} using swt dialog
      */
-    public CommonPlugin() {
-               SmartDevelopmentBridge.init();
-               String sdbPath = InstallPathConfig.getSDKPath() + File.separator + "SDK" + File.separator +"sdb" + File.separator + "sdb";
-               SmartDevelopmentBridge.createBridge(sdbPath, true);
-    }
+    protected EclipsePrompter prompter = null;
+    
+    /**
+     * {@link Executor} with {@link SWTPrompter}
+     */
+    protected Executor executor = null;
+    
+    protected RepositorySelector selector = null;
 
     /*
      * (non-Javadoc)
      * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
      */
+    @Override
     public void start(BundleContext context) throws Exception {
-        super.start(context);
+        super.start( context );
         plugin = this;
+        initializeExecutor();
+
+        String sdbPath = InstallPathConfig.getSDBPath();
+        if (!HostUtil.exists(sdbPath)) {
+            DialogUtil.openMessageDialog("There is no " + sdbPath + ".");
+        }
+        else {
+            try {
+                SmartDevelopmentBridge.init();
+                SmartDevelopmentBridge.createBridge(sdbPath, true);
+            } catch (Throwable t) {
+                Logger.error("Problem occurred while initializing sdb", t.getMessage(), t);
+                DialogUtil.openErrorDialog("Failed to start sdb");
+            }
+        }
+
+        if (OSChecker.isWindows()) {
+            String dllPath = InstallPathConfig.getSdbWinUsbApiPath();
+            if (!HostUtil.exists(dllPath))
+                DialogUtil.openMessageDialog("There is no " + dllPath + ".\n" +
+                        "It's not mandatory but you may have problem in using sdb through USB.");
+        }
     }
 
     /*
      * (non-Javadoc)
      * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
      */
+    @Override
     public void stop(BundleContext context) throws Exception {
+        finalizeExecutor();
         plugin = null;
         super.stop(context);
     }
+    
+
+    public static void setDefault( CommonPlugin plugin )
+    {
+        CommonPlugin.plugin = plugin;
+    }
 
     /**
      * Returns the shared instance
@@ -84,39 +122,56 @@ public class CommonPlugin extends AbstractUIPlugin {
     public static CommonPlugin getDefault() {
         return plugin;
     }
-    
-    @Override
 
-       protected void initializeDefaultPreferences(IPreferenceStore store) {
-       if (loadSdkPath() != null)
-               store.setDefault(TizenBasePreferencePage.KEY_SDKLOCATION,loadSdkPath());
-       store.setDefault(TizenBasePreferencePage.KEY_SDKUPDATE,TizenBasePreferencePage.VALUE_SDKUPDATE_DEFAULT);
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeDefaultPreferences(org.eclipse.jface.preference.IPreferenceStore)
+     */
+    @Override
+    protected void initializeDefaultPreferences( final IPreferenceStore store ) {
+        if (InstallPathConfig.getSDKPath() != null)
+            store.setDefault(TizenBasePreferencePage.KEY_SDKLOCATION, InstallPathConfig.getSDKPath());
+        store.setDefault(TizenBasePreferencePage.KEY_SDKUPDATE, TizenBasePreferencePage.VALUE_SDKUPDATE_DEFAULT);
+    }
 
-       }
+    /**
+     * Set {@link Executor} in eclipse plugin environment
+     * 
+     * @param executor {@link Executor}
+     */
+    public void setExecutor( final Executor executor )
+    {
+        this.executor = executor;
+    }
+    
+    /**
+     * Return {@link Executor} in eclipse plugin environment
+     * @return
+     */
+    public Executor getExecutor()
+    {
+        return this.executor;
+    }
+    
+    /**
+     * Return {@link Prompter} in eclipse plugin environment
+     * 
+     * @return {@link Prompter}
+     */
+    public Prompter getPrompter()
+    {
+        return this.prompter;
+    }
 
-       
-       /**
-        * get sdk path 
-        */
-       private String loadSdkPath() {
-               String sdkConfig;
-               String sdkPath = null;;
-               if (OSChecker.isWindows()) 
-                       sdkConfig = System.getenv("localappdata") + File.separatorChar + SDKSUFFIX;                             
-               else
-                       sdkConfig= System.getProperty("user.home") + File.separatorChar + SDKSUFFIX;    
+    protected void initializeExecutor()
+    {
+        this.prompter = new EclipsePrompter( new SWTPrompter() );
+        
+        this.executor = new EclipseExecutor( prompter );
+    }
 
-               if (HostUtil.exists(sdkConfig)) {
-                       String contents = HostUtil.getContents(sdkConfig);
-                       if (contents != null) {
-                               String[] fileContent = contents.split("=");
-                               if (fileContent.length == 2) {
-                                       if (HostUtil.exists(fileContent[1])) 
-                                               sdkPath = fileContent[1];
-                               }
-                       }
-               }
-               return sdkPath;
-       }
+    protected void finalizeExecutor()
+    {
+        
+    }
 
 }
@@ -1,43 +1,45 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-\r
-public class DefaultTableModel extends AbstractTableModel {\r
-\r
-       public DefaultTableModel(AbstractTableVO source) {\r
-               super(source);\r
-       }\r
-\r
-       public String getSourceName() {\r
-               String str = this.source.getClass().getSimpleName();\r
-               if(str.endsWith("VO")) //$NON-NLS-1$\r
-                       str = str.substring(0,str.length()-2);\r
-               return str;\r
-       }\r
-}\r
-\r
-\r
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Kangho Kim <kh5325.kim@samsung.com>
+* Hyeongseok Heo <hyeongseok.heo@samsung.com>
+* BonYong Lee <bonyong.lee@samsung.com>
+* Gyeongseok Seo <gyeongseok.seo@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.common;
+
+/**
+ * Factory Interface that are using when create new object by Factory pattern
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * @author Gyeongseok Seo <gyeongseok.seo@samsung.com>
+ */
+public interface Factory<T>
+{
+    /**
+     * create object
+     * 
+     * @return created <code>T</code> object
+     */
+    T create();
+}
@@ -1,50 +1,45 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.control;\r
-\r
-import org.eclipse.jface.viewers.IStructuredContentProvider;\r
-import org.eclipse.jface.viewers.Viewer;\r
-import org.tizen.common.model.ITableModel;\r
-\r
-\r
-public class TableViewContentProvider   implements IStructuredContentProvider {\r
-\r
-       public TableViewContentProvider() {\r
-       }\r
-\r
-       public Object[] getElements(Object model) {\r
-               return ((ITableModel)model).getDatas();\r
-       }\r
-\r
-       public void dispose() {\r
-               \r
-       }\r
-\r
-       public void inputChanged(Viewer viewer, Object obj, Object obj1) {\r
-               \r
-       }\r
-\r
-}\r
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Kangho Kim <kh5325.kim@samsung.com>
+* Hyeongseok Heo <hyeongseok.heo@samsung.com>
+* BonYong Lee <bonyong.lee@samsung.com>
+* Gyeongseok Seo <gyeongseok.seo@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.common;
+
+/**
+ * Factory Interface that are using when create new object with argument by Factory pattern
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * @author Gyeongseok Seo <gyeongseok.seo@samsung.com>
+ */
+public interface FactoryWithArgument<T, A> {
+    /**
+     * create object
+     * 
+     * @param arg argument of an object to be created
+     * @return created <code>T</code> object
+     */
+    T create( A arg );
+}
diff --git a/org.tizen.common/src/org/tizen/common/IApplicationConfiguration.java b/org.tizen.common/src/org/tizen/common/IApplicationConfiguration.java
new file mode 100755 (executable)
index 0000000..325223d
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Common\r
+ * \r
+ * Copyright (C) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Jihoon Song <jihoon80.song@samsung.com>\r
+ * Kangho Kim <kh5325.kim@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.common;\r
+\r
+/**\r
+ * IApplicationConfiguration Interface that is used when getting project's build configurations.\r
+ *\r
+ * @author Kangho Kim{@literal <kh5325.kim@samsung.com>} (S-Core)\r
+ * @author Yoonki Park <yoonki.park@samsung.com>\r
+ */\r
+public interface IApplicationConfiguration {\r
+    public String getDefaultConfiguration();\r
+    public String getBinaryName();\r
+    public String generateAppId();\r
+    public TizenProjectType getTizenProjectType();\r
+}\r
diff --git a/org.tizen.common/src/org/tizen/common/Surrogate.java b/org.tizen.common/src/org/tizen/common/Surrogate.java
new file mode 100644 (file)
index 0000000..c752d78
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Kangho Kim <kh5325.kim@samsung.com>
+* Hyeongseok Heo <hyeongseok.heo@samsung.com>
+* BonYong Lee <bonyong.lee@samsung.com>
+* Gyeongseok Seo <gyeongseok.seo@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.common;
+
+/**
+ * Surrogate Interface that are using when dependency object is injected by surrogate pattern
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * @author Gyeongseok Seo <gyeongseok.seo@samsung.com>
+ */
+public interface Surrogate<T> {
+    /**
+     * pass adapted object
+     * 
+     * @return adapted <code>T</code> object
+     */
+    T getAdapter();
+}
@@ -1,32 +1,42 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.control;\r
-\r
-import org.eclipse.jface.viewers.LabelProvider;\r
-\r
-public class TreeViewLabelProvider extends LabelProvider {\r
-       \r
-}\r
+/*
+*  Common
+*
+* 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.common;
+
+/**
+ * Surrogate Interface that are using when dependency object is injected by surrogate pattern
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface SurrogateWithArgument<T, A>
+{
+    /**
+     * pass adapted object using argument
+     * 
+     * @param arg argument of an object to be created
+     * 
+     * @return adapted <code>T</code> object
+     */
+    T getAdapter( A arg );
+}
diff --git a/org.tizen.common/src/org/tizen/common/TizenHelpContextIds.java b/org.tizen.common/src/org/tizen/common/TizenHelpContextIds.java
new file mode 100644 (file)
index 0000000..c543ddc
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact:
+* Changhyun Lee <changhyun1.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.common;
+
+public class TizenHelpContextIds
+{
+    public static final String HELP_COMMON_CONNECTION_EXPLORER_CONTEXT = "org.tizen.ide.common.connection_explorer_context";
+    public static final String HELP_COMMON_LOG_CONTEXT = "org.tizen.ide.common.log_context";
+
+    public static final String HELP_NATIVE_CODECOVERAGE_CONTEXT = "org.tizen.ide.native.codecoverage_context";
+    public static final String HELP_NATIVE_UNITTEST_CONTEXT = "org.tizen.ide.native.unittest_context";
+    public static final String HELP_NATIVE_MANIFEST_CONTEXT = "org.tizen.ide.native.manifest_context";
+    public static final String HELP_NATIVE_PROJECT_WIZARD_CONTEXT = "org.tizen.ide.native.project_wizard_context";
+
+    public static final String HELP_WEB_WIDGET_CONFIGURATION_EDITOR_CONTEXT = "org.tizen.ide.web.widget_configuration_editor_context";
+    public static final String HELP_WEB_HTML_EDITOR_CONTEXT = "org.tizen.ide.web.html_editor_context";
+    public static final String HELP_WEB_JAVASCRIPT_EDITOR_CONTEXT = "org.tizen.ide.web.javascript_editor_context";
+    public static final String HELP_WEB_CSS_EDITOR_CONTEXT = "org.tizen.ide.web.css_editor_context";
+    public static final String HELP_WEB_HTML_PREVIEW_CONTEXT = "org.tizen.ide.web.html_preview_context";
+    public static final String HELP_WEB_CSS_PREVIEW_CONTEXT = "org.tizen.ide.web.css_preview_context";
+    public static final String HELP_WEB_PREFERENCES_CONTEXT = "org.tizen.ide.web.preferences_context";
+    public static final String HELP_WEB_SIMULATOR_PREFERENCES_CONTEXT = "org.tizen.ide.web.simulator_preferences_context";
+    public static final String HELP_WEB_NEW_PROJECT_WIZARD_CONTEXT = "org.tizen.ide.web.new_project_wizard_context";
+    public static final String HELP_WEB_USER_TEMPLATE_CONTEXT = "org.tizen.ide.web.user_template_context";
+    
+}
diff --git a/org.tizen.common/src/org/tizen/common/TizenPlatformConstants.java b/org.tizen.common/src/org/tizen/common/TizenPlatformConstants.java
new file mode 100644 (file)
index 0000000..2463a98
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact:
+* Kangho Kim <kh5325.kim@samsung.com>
+* Hyunsik Noh <hyunsik.noh@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.common;
+
+import org.tizen.common.util.OSChecker;
+
+/**
+ * All constant definitions related Tizen Platform such as Emulator or Device.
+ * @author Kangho Kim {@literal <kh5325.kim@samsung.com>} (S-Core)
+ */
+public class TizenPlatformConstants {
+    // Definitions for common
+    public static final String LOCALHOST = "127.0.0.1";
+    public static final String ENVIRONMENT_SETTING_CMD = "export ";
+    public static final String CMD_RESULT_CHECK  = "; echo $?;";
+    public static final String CMD_RESULT_PREFIX  = "cmd_ret:";
+    public static final String CMD_SUFFIX  = "; echo "+CMD_RESULT_PREFIX+"$?;";
+    public static final String CMD_SUCCESS  = CMD_RESULT_PREFIX+"0";
+    public static final String CMD_FAILURE  = CMD_RESULT_PREFIX+"1";
+    
+    public static final int OS  = OSChecker.LINUX;
+
+    // Definitions for building
+
+    // Definitions for packaging
+    public static final String PACKAGENAME_PREFIX = "org.tizen";
+    public static final String DEBIAN_INSTALL_PATH = "opt/*";
+
+    // Definitions for debugging
+    public static final String PUBICL_PLATFORM_CORE_PATH = "/opt/bs/core";
+    public static final String PRIVATE_PLATFORM_CORE_PATH = "/opt/share/hidden_storage/SLP_debug";
+    public static final String GDBSERVER_CMD = TizenPlatformConstants.TOOLS_TARGET_PATH + "/gdbserver/gdbserver";
+    public static final String GDBSERVER_PLATFORM_CMD = TizenPlatformConstants.TOOLS_TARGET_PATH + "/gdbserver-platform/gdbserver";
+    public static final String ATTACH_OPTION = " --attach ";
+
+    // Definitions for installing
+    public static final String APP_INSTALL_PATH = "/opt/apps";
+    public static final String TEMPORARY_PKG_PATH = "/opt/apps/PKGS/";
+    public static final String PKG_TOOL_LIST_COMMAND = "pkgcmd -l  | grep %s";
+    public static final String PKG_TOOL_REMOVE_COMMAND = "pkgcmd -q -u -t %s -n %s";
+    public static final String PKG_TOOL_INSTALL_COMMAND = "pkgcmd -q -i -t %s -p %s";
+
+    // Definitions for launching
+    public static final String LAUNCH_CMD = "launch_app %s";
+    public static final String LAUNCH_CMD_SUCCESS = "... successfully launched";
+    public static final String LAUNCH_CMD_FAILURE = "... launch failed";
+    public static final String ELM_SCALE_GETTER = "/home/developer/sdk_tools/elm_scale_getter/get_elm_scale ";//FIXME : have to be removed
+
+    // Definitions for ondemand install
+    public static final String CONTROL_EXTENSION = ".control";
+    public static final String TOOLS_TARGET_PATH = "/home/developer/sdk_tools";
+
+    // Definitions for others
+    public static final String CODE_COVERAGE_BUILD_OPTION = "-fprofile-arcs -ftest-coverage";
+    public static final String CODE_COVERAGE_LAUNCH_OPTION = " __AUL_SDK__ CODE_COVERAGE";
+}
diff --git a/org.tizen.common/src/org/tizen/common/TizenProjectType.java b/org.tizen.common/src/org/tizen/common/TizenProjectType.java
new file mode 100644 (file)
index 0000000..126151b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+* TizenProjectType.java
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact:
+* Kangho Kim <kh5225.kim@samsung.com>
+* Gun Kim <gune.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.common;
+
+/**
+ * Represents that TIZEN supports the given project types.
+ */
+public enum TizenProjectType {
+    TIZEN_C_UI_APPLICATION,
+    TIZEN_C_SERVICE_APPLICATION,
+    TIZEN_C_SHAREDLIBRARY,
+    TIZEN_C_STATICLIBRARY,
+    TIZEN_CPP_UI_APPLICATION,
+    TIZEN_CPP_SERVICE_APPLICATION,
+    TIZEN_CPP_SHAREDLIBRARY,
+    TIZEN_CPP_STATICLIBRARY,
+    TIZEN_PLATFORM_PROJECT;
+}
diff --git a/org.tizen.common/src/org/tizen/common/cache/ImageCache.java b/org.tizen.common/src/org/tizen/common/cache/ImageCache.java
deleted file mode 100644 (file)
index 639a797..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Changhyun Lee <changhyun1.lee@samsung.com>\r
-* Kangho Kim <kh5325.kim@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.common.cache;\r
-\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-\r
-import org.eclipse.swt.graphics.Image;\r
-import org.eclipse.swt.widgets.Display;\r
-\r
-/**\r
- * Class for caching images\r
- * \r
- * @author Emil\r
- */\r
-public class ImageCache {\r
-\r
-    private static HashMap<String, Image> _ImageMap;\r
-\r
-    // what path to get to the "icons" directory without actually including it\r
-    private static final String           ICON_ROOT_PATH = "icons/";\r
-\r
-    static {\r
-        _ImageMap = new HashMap<String, Image>();\r
-    }\r
-\r
-    /**\r
-     * Returns an image that is also cached if it has to be created and does not already exist in the cache.\r
-     * \r
-     * @param fileName Filename of image to fetch\r
-     * @return Image null if it could not be found\r
-     */\r
-    public static Image getImage(String fileName) {\r
-        fileName = ICON_ROOT_PATH + fileName;\r
-        Image image = _ImageMap.get(fileName);\r
-        if (image == null) {\r
-            image = createImage(fileName);\r
-            _ImageMap.put(fileName, image);\r
-        }\r
-        return image;\r
-    }\r
-\r
-    // creates the image, and tries really hard to do so\r
-    private static Image createImage(String fileName) {\r
-        ClassLoader classLoader = ImageCache.class.getClassLoader();\r
-        InputStream is = classLoader.getResourceAsStream(fileName);\r
-        if (is == null) {\r
-            // the old way didn't have leading slash, so if we can't find the image stream,\r
-            // let's see if the old way works.\r
-            is = classLoader.getResourceAsStream(fileName.substring(1));\r
-\r
-            if (is == null) {\r
-                is = classLoader.getResourceAsStream(fileName);\r
-                if (is == null) {\r
-                    is = classLoader.getResourceAsStream(fileName.substring(1));\r
-                    if (is == null) { return null; }\r
-                }\r
-            }\r
-        }\r
-\r
-        Image img = new Image(Display.getDefault(), is);\r
-        try {\r
-            is.close();\r
-        } catch (IOException e) {\r
-            e.printStackTrace();\r
-        }\r
-\r
-        return img;\r
-    }\r
-\r
-    /**\r
-     * Disposes ALL images that have been cached.\r
-     */\r
-    public static void dispose() {\r
-        Iterator<Image> e = _ImageMap.values().iterator();\r
-        while (e.hasNext())\r
-            e.next().dispose();\r
-\r
-    }\r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/control/TableViewCellModifier.java b/org.tizen.common/src/org/tizen/common/control/TableViewCellModifier.java
deleted file mode 100644 (file)
index 6bbc54e..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.control;\r
-import org.eclipse.jface.viewers.CellEditor;\r
-import org.eclipse.jface.viewers.ComboBoxCellEditor;\r
-import org.eclipse.jface.viewers.ICellModifier;\r
-import org.eclipse.jface.viewers.TableViewer;\r
-import org.eclipse.jface.viewers.TextCellEditor;\r
-import org.eclipse.swt.widgets.TableColumn;\r
-import org.eclipse.swt.widgets.TableItem;\r
-import org.tizen.common.model.ITableVO;\r
-\r
-\r
-/**\r
- * This class implements an ICellModifier\r
- * An ICellModifier is called when the user modifes a cell in the \r
- * tableViewer\r
- */\r
-\r
-public class TableViewCellModifier implements ICellModifier {\r
-       private TableViewer viewer;\r
-       private String[] columnNames;\r
-       CellEditor[] cellEditors;\r
-       /**\r
-        * Constructor \r
-        * @param TableViewerExample an instance of a TableViewerExample \r
-        */\r
-       public TableViewCellModifier(TableViewer viewer) {\r
-               super();\r
-               this.viewer = viewer;\r
-               this.columnNames = getColumnNames();\r
-               this.viewer.setColumnProperties(columnNames);\r
-       }\r
-\r
-       private String[] getColumnNames() {\r
-               TableColumn[] columns = viewer.getTable().getColumns();\r
-               String[] columnNames = new String[columns.length];\r
-               for(int i=0;i<columnNames.length;i++){\r
-                       columnNames[i] = columns[i].getText();\r
-               }\r
-               \r
-               return columnNames;\r
-       }\r
-\r
-       /**\r
-        * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String)\r
-        */\r
-       public boolean canModify(Object element, String property) {\r
-               return true;\r
-       }\r
-\r
-       /**\r
-        * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, java.lang.String)\r
-        */\r
-       public Object getValue(Object element, String property) {\r
-               \r
-               Object result = null;\r
-               int idx = getColumnIndex(property);\r
-               ITableVO vo = (ITableVO)element;\r
-               \r
-               CellEditor ce = getCellEditor(idx);\r
-               \r
-               if(ce instanceof ComboBoxCellEditor){\r
-                       result = vo.getColumnValue(idx);\r
-               }else if(ce instanceof TextCellEditor){\r
-                       result =  vo.getColumnValue(idx);\r
-               }else{\r
-                               result = ""; //$NON-NLS-1$\r
-               }\r
-               return result;  \r
-       }\r
-\r
-       private CellEditor getCellEditor(int idx) {\r
-               if(this.cellEditors==null)\r
-                       this.cellEditors = viewer.getCellEditors();\r
-               return this.cellEditors[idx];\r
-       }\r
-\r
-       private int getColumnIndex(String property) {\r
-               for(int i=0;i<columnNames.length;i++){\r
-                       if(columnNames[i].equals(property))\r
-                               return i;\r
-               }\r
-               return 0;\r
-       }\r
-       \r
-       private int getComboIndex(String[] items, Object str) {\r
-               for(int i=0;i<items.length;i++){\r
-                       if(items[i].equals(str))\r
-                               return i;\r
-               }\r
-               return 0;\r
-       }\r
-\r
-       /**\r
-        * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, java.lang.String, java.lang.Object)\r
-        */\r
-       public void modify(Object element, String property, Object value) {     \r
-               int idx = getColumnIndex(property);\r
-               ITableVO vo = (ITableVO)((TableItem) element).getData();\r
-               \r
-               if(cellEditors[idx] instanceof ComboBoxCellEditor){\r
-                       if((Integer)value < 0)\r
-                               return;\r
-                       else\r
-                               vo.setColumnValue(idx, value);\r
-               }else if(cellEditors[idx] instanceof TextCellEditor){\r
-                       vo.setColumnValue(idx, value);\r
-               }\r
-               \r
-               viewer.update(vo, null);\r
-       }\r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/control/TableViewColumnSorter.java b/org.tizen.common/src/org/tizen/common/control/TableViewColumnSorter.java
deleted file mode 100644 (file)
index 1456f89..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.control;\r
-\r
-import java.util.Comparator;\r
-\r
-import org.eclipse.jface.viewers.TableViewer;\r
-import org.eclipse.jface.viewers.Viewer;\r
-import org.eclipse.jface.viewers.ViewerSorter;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.SelectionAdapter;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.graphics.Cursor;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Table;\r
-import org.eclipse.swt.widgets.TableColumn;\r
-import org.tizen.common.model.ITableVO;\r
-\r
-\r
-\r
-\r
-/**\r
- * A viewer sorter is used by a structured viewer to reorder the elements\r
- * provided by its content provider. In addition, the TableViewColumnSorter\r
- * listens for mouse clicks in the column headers and resorts the table content\r
- * based on the column that was selected. Clicking on a column a second time\r
- * toggles the sort order.\r
- */\r
-public class TableViewColumnSorter extends ViewerSorter {\r
-       private static final String COLUMN_INDEX_KEY = "COLUMN_INDEX"; //$NON-NLS-1$\r
-       private static final String HEADER_TEXT_KEY = "HEADER_TEXT"; //$NON-NLS-1$\r
-       private static final String TAG_DESCENDING = "\u25b2"; // up-pointing triangle\r
-       private static final String TAG_ASCENDING = "\u25bc"; // down-pointing triangle\r
-       \r
-       private TableViewer viewer;\r
-       private Table table;\r
-       private TableColumn[] columns;\r
-       Cursor waitCursor;\r
-       \r
-       private Comparator<String> stringComparator = new Comparator<String>(){\r
-               @Override\r
-               public int compare(String str1, String str2) {\r
-                       str1=str1==null?"":str1; //$NON-NLS-1$\r
-                       str2=str2==null?"":str2; //$NON-NLS-1$\r
-                       return str1.compareTo(str2);\r
-               }\r
-       };\r
-       \r
-       private Comparator<Integer> numberComparator = new Comparator<Integer>(){\r
-               @Override\r
-               public int compare(Integer num1, Integer num2) {\r
-                       return num1>num2?1:(num1==num2?0:-1);\r
-               }\r
-       };\r
-\r
-       public TableViewColumnSorter(TableViewer viewer) {\r
-               this.viewer = viewer;\r
-               this.table = viewer.getTable();\r
-               this.columns = viewer.getTable().getColumns();\r
-               \r
-               createCursor();\r
-               createSelectionListener(columns);\r
-       }\r
-\r
-       private void createCursor(){\r
-               waitCursor = Display.getCurrent().getSystemCursor(SWT.CURSOR_WAIT);\r
-       }\r
-       \r
-       public int compare(Viewer viewer, Object object1, Object object2) {\r
-               TableColumn column = table.getSortColumn();\r
-               \r
-               int index = -1;\r
-               if(column==null){\r
-                       return 0;\r
-               }else{\r
-                       index = (Integer)column.getData(COLUMN_INDEX_KEY);\r
-               }\r
-               \r
-               Object target1 = ((ITableVO)object1).getColumnValue(index);\r
-               Object target2 = ((ITableVO)object2).getColumnValue(index);\r
-               \r
-               int result = compare(target1, target2);\r
-               \r
-               if(table.getSortDirection()==SWT.UP)\r
-                       return result;\r
-               else\r
-                       return -result;\r
-       }\r
-       \r
-       public int compare(Object object1, Object object2){\r
-               if(object1 instanceof Integer){\r
-                       return numberComparator.compare((Integer)object1, (Integer)object2);\r
-               }else{\r
-                       return stringComparator.compare(object1.toString(), object2.toString());\r
-               }\r
-       }\r
-\r
-       private void createSelectionListener(TableColumn[] columns) {\r
-               for (int i = 0; i < columns.length; i++) {\r
-                       columns[i].setData(COLUMN_INDEX_KEY,i);\r
-                       columns[i].setData(HEADER_TEXT_KEY,columns[i].getText());\r
-                       columns[i].addSelectionListener(new SelectionAdapter() {\r
-                               @Override\r
-                               public void widgetSelected(SelectionEvent e) {\r
-                                       TableColumn column = (TableColumn)e.getSource();\r
-                                       clearColumnHeader(column);\r
-                                       renderColumnHeader(column);\r
-                                       \r
-                                       table.setCursor(waitCursor);\r
-                                       viewer.refresh();\r
-                                       table.setCursor(null);\r
-                               }\r
-                       });\r
-               }\r
-       }\r
-       \r
-       private void renderColumnHeader(TableColumn column){\r
-               int direction = table.getSortDirection()==SWT.UP?SWT.DOWN:SWT.UP;\r
-               table.setSortDirection(direction);\r
-               table.setSortColumn(column);\r
-               \r
-               String title = (String)column.getData(HEADER_TEXT_KEY);\r
-               String directionShape = direction==SWT.UP?TAG_DESCENDING:TAG_ASCENDING;\r
-               column.setText(title+" "+directionShape); //$NON-NLS-1$\r
-       }\r
-       \r
-       private void clearColumnHeader(TableColumn column){\r
-               TableColumn prevColumn = table.getSortColumn();\r
-               \r
-               if(prevColumn==null){\r
-                       return;\r
-               }else{\r
-                       prevColumn.setText((String)prevColumn.getData(HEADER_TEXT_KEY));\r
-               }\r
-       }\r
-\r
-}
\ No newline at end of file
diff --git a/org.tizen.common/src/org/tizen/common/control/TableViewLabelProvider.java b/org.tizen.common/src/org/tizen/common/control/TableViewLabelProvider.java
deleted file mode 100644 (file)
index 12bfa05..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.control;\r
-\r
-import java.lang.reflect.Field;\r
-import java.lang.reflect.Method;\r
-\r
-import org.eclipse.jface.viewers.CellEditor;\r
-import org.eclipse.jface.viewers.ColumnLabelProvider;\r
-import org.eclipse.jface.viewers.ComboBoxCellEditor;\r
-import org.eclipse.jface.viewers.ITableLabelProvider;\r
-import org.eclipse.jface.viewers.TableViewer;\r
-import org.eclipse.swt.graphics.Image;\r
-import org.tizen.common.model.ITableVO;\r
-\r
-\r
-\r
-\r
-\r
-public class TableViewLabelProvider  extends ColumnLabelProvider implements ITableLabelProvider {\r
-\r
-       public TableViewLabelProvider() {\r
-       }\r
-       \r
-       private TableViewer viewer;\r
-       CellEditor[] cellEditors;\r
-       \r
-       public TableViewLabelProvider(TableViewer viewer) {\r
-               this.viewer = viewer;\r
-               this.cellEditors = viewer.getCellEditors();\r
-       }\r
-       \r
-       private Field[] fields;\r
-       \r
-       private int getColumnIndex(int columnIndex){\r
-               return fields.length>columnIndex?columnIndex:fields.length;\r
-       }\r
-\r
-       public Image getColumnImage(Object element, int columnIndex) {\r
-               return null;\r
-       }\r
-       \r
-//     private void hasCellEditor(){\r
-//             if(this.cellEditors==null)\r
-//                     this.cellEditors = viewer.getCellEditors();\r
-//     }\r
-       \r
-       private CellEditor getCellEditor(int idx) {\r
-               if(this.cellEditors==null)\r
-                       return null;\r
-               else\r
-                       return this.cellEditors[idx];\r
-       }\r
-\r
-       public String getColumnText(Object element, int columnIndex) {\r
-               Object obj = null;\r
-               \r
-               if(element instanceof ITableVO){\r
-                       ITableVO data = (ITableVO)element;\r
-                       if(this.cellEditors != null){\r
-                               CellEditor ce = getCellEditor(columnIndex);\r
-                               if(ce instanceof ComboBoxCellEditor){\r
-                                       ComboBoxCellEditor editor = (ComboBoxCellEditor)ce;\r
-                                       String items[] = editor.getItems();\r
-                                       int idx = (Integer) data.getColumnValue(columnIndex);\r
-                                       if(idx<0)\r
-                                               obj = null;\r
-                                       else if(idx>items.length)\r
-                                               obj = items[0];\r
-                                       else\r
-                                               obj = items[idx];\r
-                               }else{\r
-                                       obj = data.getColumnValue(columnIndex);\r
-                               }\r
-                       }else{\r
-                               obj = data.getColumnValue(columnIndex);\r
-                       }\r
-               }else{\r
-                       if(fields==null)\r
-                               fields = element.getClass().getDeclaredFields();\r
-                       \r
-                       int idx = getColumnIndex(columnIndex);\r
-                       String fieldName = fields[idx].getName().substring(0, 1).toUpperCase()          \r
-                       + fields[idx].getName().substring(1,fields[idx].getName().length());\r
-                       \r
-                       try{\r
-                               Method method = element.getClass().getMethod("get" + fieldName, new Class[] {}); //$NON-NLS-1$\r
-                               obj = method.invoke(element, new Object[] {});\r
-                       }catch(Exception e){\r
-                               return ""; //$NON-NLS-1$\r
-                       }\r
-               }       \r
-               \r
-               return obj==null?"":String.valueOf(obj); //$NON-NLS-1$\r
-       }\r
-\r
-\r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/control/TreeViewContentProvider.java b/org.tizen.common/src/org/tizen/common/control/TreeViewContentProvider.java
deleted file mode 100644 (file)
index 726fb93..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.control;\r
-\r
-import org.eclipse.jface.viewers.ITreeContentProvider;\r
-import org.eclipse.jface.viewers.Viewer;\r
-import org.tizen.common.model.ITreeModel;\r
-import org.tizen.common.model.ITreeVO;\r
-\r
-\r
-public class TreeViewContentProvider    implements ITreeContentProvider {\r
-\r
-       public Object[] getChildren(Object element) {\r
-               if(element instanceof ITreeModel)\r
-                       return ((ITreeModel)element).getDatas();\r
-               else\r
-                       return ((ITreeVO)element).getChildren();\r
-       }\r
-\r
-       public Object getParent(Object element) {\r
-               if(element instanceof ITreeModel)\r
-                       return null;\r
-               else\r
-                       return ((ITreeVO)element).getParent();\r
-               \r
-       }\r
-\r
-       public boolean hasChildren(Object element) {\r
-               if(element instanceof ITreeModel)\r
-                       return ((ITreeModel)element).size()>0;\r
-               else\r
-                       return ((ITreeVO)element).hasChildren();\r
-       }\r
-\r
-       public Object[] getElements(Object inputElement) {\r
-               return getChildren(inputElement);\r
-       }\r
-       \r
-       public void dispose() {\r
-       }\r
-\r
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
-       }\r
-\r
-\r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/core/application/InstallPathConfig.java b/org.tizen.common/src/org/tizen/common/core/application/InstallPathConfig.java
new file mode 100644 (file)
index 0000000..d0d268e
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact:
+* 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.common.core.application;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.tizen.common.util.DialogUtil;
+import org.tizen.common.util.HostUtil;
+import org.tizen.common.util.OSChecker;
+
+
+
+final public class InstallPathConfig {
+
+    private static String defaultHomePath;
+    private static String sdkInstallPath;
+
+    private static final String DIR_PLATFORMS = "platforms";
+    private static final String DIR_PLATFORMS_VER = "tizen2.0";
+    private static final String DIR_SAMPLES = "samples";
+    private static final String DIR_SNIPPETS = "snippets";
+    private static final String DIR_ON_DEMAND = "on-demand";
+    private static final String DIR_EMULATOR = "emulator";
+    private static final String DIR_INSTALLER = "install-manager";
+    private static final String DIR_TOOLS = "tools";
+    private static final String DIR_LIBRARY = "library";
+    private static final String DIR_SDK_DATA = "tizen-sdk-data";
+
+    private final static String SDKSUFFIX = DIR_SDK_DATA + File.separatorChar + "tizensdkpath";
+
+    // Registry Key
+    private static final String REGISTRY_PATH_OF_SHELL_FOLDER = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
+    // public static final String REGISTRY_APP_DATA_OF_SHELL_FOLDER = "AppData";
+    private static final String REGISTRY_LOCAL_APP_DATA_OF_SHELL_FOLDER = "\"Local AppData\"";
+    // Value Column
+    private static final String REG_SZ = "REG_SZ";
+
+    static {
+        // FIXME : don't need the following lines if using environment variable
+        if (OSChecker.isWindows()) {
+            defaultHomePath = getRegistryValue(REGISTRY_PATH_OF_SHELL_FOLDER,REGISTRY_LOCAL_APP_DATA_OF_SHELL_FOLDER) ;
+        } else if (OSChecker.isLinux() == true || OSChecker.isUnix() == true || OSChecker.isMAC() == true) {
+            defaultHomePath = System.getProperty("user.home");
+        } else {
+            DialogUtil.openMessageDialog(System.getProperty("os.name") + " is not supported currently.");
+            System.exit(0);
+        }
+
+        loadSdkPath(defaultHomePath + File.separatorChar + SDKSUFFIX);
+    }
+
+    /**
+     * @deprecated Use {@link #getSDKPath()} instead.
+     */
+    @Deprecated
+    public static String getIDEPath() {
+        // FIXME : can't help but putting the code due to the Web IDE path , It has to be removed soon.
+        return System.getProperty("user.dir");
+    }
+
+    public static String getSDKPath() {
+        return sdkInstallPath;
+    }
+
+    //This is temporary code to get platform version path(only for one).
+    //TODO: Should change to return string array type for various platform version paths.
+    public static String getPlatformVersionPath()
+    {
+        String path = null;
+        String platformPath = getSDKPath() + File.separator + DIR_PLATFORMS;
+        File platforms = new File(platformPath);
+        if(platforms.isDirectory())
+        {
+            // platforms.listFiles[0] can cause undetermined result like platforms/tmp.ini/sample
+            path = platformPath + File.separator + DIR_PLATFORMS_VER;
+        }
+        return path;
+    }
+
+    //TODO: Should change to get string array type for various platform version paths.
+    public static String getSamplesPath()
+    {
+        return getPlatformVersionPath() + File.separator + DIR_SAMPLES;
+    }
+
+    //TODO: Should change to get string array type for various platform version paths.
+    public static String getSnippetsPath()
+    {
+        return getPlatformVersionPath() + File.separator + DIR_SNIPPETS;
+    }
+
+    //TODO: Should change to get string array type for various platform version paths.
+    public static String getOnDemandPath()
+    {
+        return getPlatformVersionPath() + File.separator + DIR_ON_DEMAND;
+    }
+
+    public static String getLibraryPath() {
+        return getSDKPath() + File.separator + DIR_LIBRARY;
+    }
+
+    private static String getToolsPath() {
+        return getSDKPath() + File.separator + DIR_TOOLS;
+    }
+
+    public static String getSDBPath() {
+        String toolsPath = getToolsPath();
+        if (OSChecker.isWindows())
+            return toolsPath + File.separator + "sdb.exe";
+        else
+            return toolsPath + File.separator + "sdb";
+    }
+
+    public static String getSdbWinUsbApiPath() {
+        return getToolsPath() + File.separator + "SdbWinUsbApi.dll";
+    }
+
+    public static String getInstallManagerPath() {
+        return getSDKPath() + File.separator + DIR_INSTALLER;
+    }
+
+    public static String getEmulatorPath() {
+        return getToolsPath() + File.separator + DIR_EMULATOR;
+    }
+
+    public static String getUserHomePath() {
+        return defaultHomePath;
+    }
+
+    public static String getUserDataPath() {
+        return getUserHomePath() + File.separator + DIR_SDK_DATA;
+    }
+
+    private static void loadSdkPath(String sdkPath) {
+        boolean status = true;
+        if (HostUtil.exists(sdkPath)) {
+            String[] fileContent = HostUtil.getContents(sdkPath).split("=");
+            if (HostUtil.exists(fileContent[1]))
+                sdkInstallPath = fileContent[1];
+            else {
+                status = false;
+            }
+        } else {
+            status = false;
+        }
+
+        if (!status) {
+            DialogUtil.openMessageDialog("Tizen SDK is not installed properly.");
+            System.exit(0);
+        }
+    }
+    private static String getRegistryValue(String node, String key) {
+        if (!OSChecker.isWindows())
+            return null;
+
+        BufferedReader br = null;
+        String value = "";
+
+        String query = "reg query " + "\"" + node + "\" /v " + key;
+        try {
+            Process process = Runtime.getRuntime().exec(query);
+            String encoding = System.getProperty("sun.jnu.encoding");
+            br = new BufferedReader(new InputStreamReader(process.getInputStream(), encoding));
+
+            String line = null;
+            while ((line = br.readLine()) != null) {
+                int index = line.indexOf(REG_SZ);
+                if (index >= 0) {
+                    value = line.substring(index + REG_SZ.length()).trim();
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return value;
+    }
+}
\ No newline at end of file
diff --git a/org.tizen.common/src/org/tizen/common/core/application/Messages.java b/org.tizen.common/src/org/tizen/common/core/application/Messages.java
new file mode 100644 (file)
index 0000000..d0ec4ae
--- /dev/null
@@ -0,0 +1,19 @@
+package org.tizen.common.core.application;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+       private static final String BUNDLE_NAME = Messages.class.getName(); //$NON-NLS-1$
+       public static String DIALOG_TITLE;
+       public static String ASK_FOR_UPDATE;
+       
+    public static String FileExistDialogTitle;
+    public static String FileExistMsg;
+    
+       static {
+               // initialize resource bundle
+               NLS.initializeMessages( BUNDLE_NAME, Messages.class );
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/application/Messages.properties b/org.tizen.common/src/org/tizen/common/core/application/Messages.properties
new file mode 100644 (file)
index 0000000..d3158eb
--- /dev/null
@@ -0,0 +1,5 @@
+DIALOG_TITLE = Tizen SDK
+ASK_FOR_UPDATE = Tizen SDK updates are available. Do you want to install them now?
+
+FileExistDialogTitle=Existing resource
+FileExistMsg="{0}" already exists. Do you want to overwrite it?
diff --git a/org.tizen.common/src/org/tizen/common/core/application/StatusLineMessageManager.java b/org.tizen.common/src/org/tizen/common/core/application/StatusLineMessageManager.java
new file mode 100644 (file)
index 0000000..7d4fa25
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * 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.common.core.application;
+
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.ui.IViewPart;
+
+public class StatusLineMessageManager
+{
+       
+       protected final IStatusLineManager manager;
+
+       /**
+        * Contructor with {@link IViewPart}
+        * 
+        * @param part {@link IViewPart} to provide {@link IStatusLineManager}
+        */
+       public StatusLineMessageManager( final IViewPart part )
+       {
+               this( part.getViewSite().getActionBars().getStatusLineManager() );
+       }
+
+       /**
+        * Constructor with {@link IStatusLineManager}
+        * 
+        * @param manager {@link IStatusLineManager} to manage status bar
+        */
+       public StatusLineMessageManager(
+               final IStatusLineManager manager
+       )
+       {
+               if ( null == manager )
+               {       // Fast Fail
+                       throw new NullPointerException();
+               }
+               this.manager = manager;
+       }
+
+       /**
+        * Add error message at status bar
+        * 
+        * @param message message to print out
+        */
+       public void setErrorMessage( final String message )
+       {
+               manager.setErrorMessage( message );
+       }
+
+       /**
+        * Add message at status bar
+        * 
+        * @param message message to print out
+        */
+       public void setMessage( final String message )
+       {
+               manager.setMessage( message );
+       }
+}
old mode 100644 (file)
new mode 100755 (executable)
similarity index 67%
rename from org.tizen.common/src/org/tizen/common/update/UpdateManager.java
rename to org.tizen.common/src/org/tizen/common/core/application/UpdateManager.java
index 1a17179..0213b27
 * - S-Core Co., Ltd
 *
 */
-package org.tizen.common.update;
+package org.tizen.common.core.application;
+
+import static org.tizen.common.util.SWTUtil.syncExec;
 
 import java.io.File;
-import java.util.ResourceBundle;
 
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IStartup;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.PlatformUI;
 import org.tizen.common.CommonPlugin;
-import org.tizen.common.preferences.TizenBasePreferencePage;
-import org.tizen.common.properties.InstallPathConfig;
+import org.tizen.common.ui.page.preference.TizenBasePreferencePage;
 import org.tizen.common.util.HostUtil;
 import org.tizen.common.util.OSChecker;
+import org.tizen.common.util.SWTUtil;
 
 
 public class UpdateManager implements IStartup {
@@ -48,49 +48,48 @@ public class UpdateManager implements IStartup {
        private static final String EXECUTE_INSTALLER_COMMAND_FOR_WINDOWS = "InstManager.exe"; 
        private static final String UPDATE_LIST_CHECK_COMMAND = "%s -checkPackageUpdate";
        private static final String RESULT_VALUE_OF_UPDATABLE = "updatable";
-       private static final String BUNDLE_NAME = UpdateManager.class.getPackage().getName() + ".UpdateMessages";//$NON-NLS-1$
-       
-       public static ResourceBundle resources = ResourceBundle.getBundle(BUNDLE_NAME);
        
        final IWorkbench workbench = PlatformUI.getWorkbench();
        
        @Override
        public void earlyStartup() {
                // Check installable package exist.
-               IPreferenceStore prefStore = CommonPlugin.getDefault().getPreferenceStore();
+               final IPreferenceStore prefStore =
+                       CommonPlugin.getDefault().getPreferenceStore();
                                
-               if(prefStore.getBoolean(TizenBasePreferencePage.KEY_SDKUPDATE))
-               {
-                       boolean updatable = isExistUpdatablePackage();
-                       if(updatable) {
-                               if(askExecuteInstallerDlg()) {
-                                       executeInstallManger();
-                                       if (workbench != null) {
-                                               final Display display = workbench.getDisplay();
-                                               display.syncExec(new Runnable() {
-                                                       public void run() {
-                                                               if (!display.isDisposed())
-                                                                       workbench.close();
-                                                       }
-                                               });
-                                       }
-                               }
-                       }
+               if ( !prefStore.getBoolean( TizenBasePreferencePage.KEY_SDKUPDATE ) )
+               {       // User don't want to update at startup
+                       return ;
                }
+               if ( !isExistUpdatablePackage() )
+               {       // Check updatable version
+                       return ;
+               }
+               if( !askExecuteInstallerDlg() )
+               {       // User don't want to update at this time
+                       return ;
+               }
+               
+               executeInstallManger();
+               syncExec( new Runnable() {
+                   public void run() {
+                       if (!workbench.getDisplay().isDisposed())
+                       {
+                           workbench.close();
+                       }
+                   }
+               });
        }
        
-       private boolean isExistUpdatablePackage() {
-               String result = HostUtil.returnExecute(getUpdateCheckCmd(), InstallPathConfig.getInstallManagerPath());
-               if(RESULT_VALUE_OF_UPDATABLE.equals(result))
-                       return true;
-               return false;
+       private boolean isExistUpdatablePackage()
+       {
+               String result = HostUtil.returnExecute( getUpdateCheckCmd(), InstallPathConfig.getInstallManagerPath() );
+               return ( RESULT_VALUE_OF_UPDATABLE.equals( result ) );
        }
        
        private boolean askExecuteInstallerDlg() {
                int ret = checkUpdate();
-               if (ret == IDialogConstants.YES_ID)
-                       return true; 
-               return false;
+               return ( ret == IDialogConstants.YES_ID );
        }
        
        private void executeInstallManger() {
@@ -112,8 +111,11 @@ public class UpdateManager implements IStartup {
                                
                                MessageDialog dialog = new MessageDialog(
                                                PlatformUI.getWorkbench().getDisplay().getActiveShell(),
-                                               resources.getString("message.dialogTitle"),
-                                               null, resources.getString("message.askForUpdate"), MessageDialog.QUESTION, labels, 0);
+                                               Messages.DIALOG_TITLE,
+                                               null,
+                                               Messages.ASK_FOR_UPDATE,
+                                               MessageDialog.QUESTION,
+                                               labels, 0);
                                dialog.open();
                                if (dialog.getReturnCode() == SWT.DEFAULT) {
                                        // A window close returns SWT.DEFAULT - mapped to a cancel
@@ -124,7 +126,8 @@ public class UpdateManager implements IStartup {
                        }
                };
 
-               PlatformUI.getWorkbench().getDisplay().syncExec(query);
+
+               SWTUtil.syncExec( query );
                return result[0];
        }
        
diff --git a/org.tizen.common/src/org/tizen/common/core/command/AbstractCommand.java b/org.tizen.common/src/org/tizen/common/core/command/AbstractCommand.java
new file mode 100644 (file)
index 0000000..a083ddc
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Common
+ *
+ * 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.common.core.command;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * AbstractCommand.
+ * 
+ * Abstract class for {@link Command}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+abstract public class
+AbstractCommand<T>
+implements Command<T> {
+       
+       /**
+        * Logger for this instance ( it will be used by sub-class )
+        */
+       protected Logger logger = LoggerFactory.getLogger( getClass() );
+       
+       /**
+        * Name of the cancel operation)
+        */
+       public static final String COMMAND_CANCEL = "cancel";
+       
+       /**
+        * Result after execution of command
+        */
+       protected T result;
+       
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Command#execute(org.tizen.common.core.command.Executor, org.tizen.common.core.command.ExecutionContext)
+        */
+       @Override
+       abstract public
+       void
+       run(
+               final Executor executor,
+               final ExecutionContext context
+       )
+       throws Exception;
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Command#undo(org.tizen.common.core.command.Executor, org.tizen.common.core.command.ExecutionContext)
+        */
+       @Override
+       public void undo(
+               final Executor executor,
+               final ExecutionContext context
+       )
+       throws Exception
+       {
+               throw new UnsupportedOperationException();
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Command#getResult()
+        */
+       @Override
+       public
+       T
+       getResult()
+       {
+               return this.result;
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/Command.java b/org.tizen.common/src/org/tizen/common/core/command/Command.java
new file mode 100644 (file)
index 0000000..c1b3f19
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command;
+
+/**
+ * <p>
+ * Command.
+ * 
+ * Behavior unit for functionality independing on environment( file system, ui, ... )
+ * </p>
+ * 
+ * @param <T> Execution result type
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface
+Command<T>
+{
+       /**
+        * Execute unit functionality
+        * 
+        * @param executor execution subject
+        * @param context execution context
+        * 
+        * @throws Exception If Exception occur in execution
+        */
+       void run( Executor executor, ExecutionContext context ) throws Exception;
+       
+       /**
+        * Execute undoing for execution if possible
+        * 
+        * @param executor execution subject
+        * @param context execution context
+        * 
+        * @throws Exception If Exception occur in undo
+        */
+       void undo( Executor executor, ExecutionContext context ) throws Exception;
+       
+       /**
+        * Return execution result
+        * 
+        * @return Execution result
+        */
+       T getResult();
+       
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/CommandCancelException.java b/org.tizen.common/src/org/tizen/common/core/command/CommandCancelException.java
new file mode 100644 (file)
index 0000000..c4e2b57
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Ho Namkoong <ho.namkoong@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.common.core.command;
+
+/**
+ * <p>
+ * CommandCancelException.
+ * 
+ * This exception is thrown when run method of command is canceled by user operation.
+ * </p>
+ * 
+ * @param <T> Execution result type
+ * 
+ * @author Ho Namkoong{@literal <ho.namkoong@samsung.com>} (S-Core)
+ * @See Command
+ */
+
+public class CommandCancelException extends RuntimeException {
+    
+    private static final long serialVersionUID = 1L;
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/CompositeCommand.java b/org.tizen.common/src/org/tizen/common/core/command/CompositeCommand.java
new file mode 100644 (file)
index 0000000..4fdfba5
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Common
+ *
+ * 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.common.core.command;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * <p>
+ * CompositeCommand.
+ * 
+ * Command to execute multiple {@link Command}s
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+CompositeCommand
+extends AbstractCommand<Object>
+{
+       
+       /**
+        * {@link Command}s to execute
+        */
+       @SuppressWarnings("rawtypes")
+       protected final ArrayList<Command> commands = new ArrayList<Command>();
+       
+       /**
+        * Constructor with {@link Command}s
+        * 
+        * @param commands {@link Command}s to execute 
+        * 
+        * @see #addCommand(Command...)
+        */
+       public
+       CompositeCommand(
+               final Command<?>... commands
+       )
+       {
+               addCommand( commands );
+       } 
+       
+       /**
+        * Add {@link Command} to {@link Command}s to execute 
+        * 
+        * @param commands
+        * 
+        * @see #commands
+        */
+       public
+       void
+       addCommand(
+               final Command<?>... commands
+       )
+       {
+               if ( null != commands )
+               {
+                       this.commands.addAll( Arrays.asList( commands ) );
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Command#execute(org.tizen.common.core.command.Executor, org.tizen.common.core.command.ExecutionContext)
+        */
+       @Override
+       public
+       void
+       run(
+               final Executor executor,
+               final ExecutionContext context
+       )
+       throws Exception
+       {
+               for ( final Command<Object> command : this.commands )
+               {
+                       command.run( executor, context );
+               }
+               
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/EclipseExecutor.java b/org.tizen.common/src/org/tizen/common/core/command/EclipseExecutor.java
new file mode 100644 (file)
index 0000000..ff02a58
--- /dev/null
@@ -0,0 +1,70 @@
+package org.tizen.common.core.command;
+
+import java.text.MessageFormat;
+
+import org.tizen.common.Factory;
+import org.tizen.common.core.command.policy.PolicyRegistry;
+import org.tizen.common.file.EclipseFileHandler;
+import org.tizen.common.file.FileHandler;
+
+public class
+EclipseExecutor
+extends Executor
+{
+       /**
+        * Contructor with prompter
+        * 
+        * @param prompter {@link Prompter}
+        */
+       public
+       EclipseExecutor(
+               final Prompter prompter
+       )
+       {
+               super(
+                       new Factory<ExecutionContext>() {
+                               
+                               /**
+                                * {@link FileHandler} for Command Line Interface
+                                */
+                               protected FileHandler fileHandler = new EclipseFileHandler();
+                               
+                               
+                               /**
+                                * <p>
+                                * {@link PolicyRegistry} for Command Line Interface
+                                * </p>
+                                */
+                               protected Factory<PolicyRegistry> factory = new PolicyRegistryFactory();
+                               
+                               /**
+                                * Create and return {@link PolicyRegistry}
+                                * 
+                                * @return {@link PolicyRegistry} to be created
+                                */
+                               protected
+                               PolicyRegistry
+                               getRegistry()
+                               {
+                                       return factory.create();
+                               }
+                               
+                               /* (non-Javadoc)
+                                * @see org.tizen.common.core.command.ExecutionContextFactory#create()
+                                */
+                               @Override
+                               public
+                               ExecutionContext
+                               create()
+                               {
+                                       return new ExecutionContext(
+                                   getRegistry(),
+                                   prompter,
+                                   fileHandler
+                                               );
+                               }
+                               
+                       }
+               );
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/ExecutionContext.java b/org.tizen.common/src/org/tizen/common/core/command/ExecutionContext.java
new file mode 100644 (file)
index 0000000..0d68c2c
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Common
+ *
+ * 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.common.core.command;
+
+import org.tizen.common.core.command.policy.PolicyRegistry;
+import org.tizen.common.file.FileHandler;
+
+/**
+ * <p>
+ * ExecutionContext.
+ * 
+ * Context in execution of commands
+ * 
+ * Container for objects in execution envitonment
+ * 
+ * It is injected by executor
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see Executor
+ */
+public class
+ExecutionContext
+{
+       /**
+        * Registry for {@link Policy}
+        */
+       protected final PolicyRegistry registry;
+       
+       /**
+        * {@link Prompter} for user interaction
+        */
+       protected final Prompter prompter;
+       
+       /**
+        * {@link FileHandler} for file system
+        */
+       protected final FileHandler fileHandler;
+       
+       
+       /**
+        * Constructor with {@link PolicyRegistry}, {@link Prompter} and {@link FileHandler}
+        * 
+        * @param registry {@link PolicyRegistry} to use
+        * @param prompter {@link Prompter} to use
+        * @param fileHandler {@link FileHandler} to use
+        */
+       public
+       ExecutionContext(
+               final PolicyRegistry registry,
+               final Prompter prompter,
+               final FileHandler fileHandler
+       )
+       {
+               this.registry= registry;
+               this.prompter = prompter;
+               this.fileHandler = fileHandler;
+       }
+       
+       
+       /**
+        * Return {@link PolicyRegistry} to be using
+        * 
+        * @return {@link PolicyRegistry}
+        */
+       public
+       PolicyRegistry
+       getPolicyRegistry()
+       {
+               return this.registry;
+       }
+       
+       /**
+        * Return {@link Policy} for <code>name</code>
+        * 
+        * @param name policy name
+        * 
+        * @return {@link Policy} matching by <code>name<code>
+        * 
+        * @see PolicyRegistry#getPolicy(String);
+        */
+       public
+       Policy
+       getPolicy(
+               final String name
+       )
+       {
+               return this.registry.getPolicy( name );
+       }
+       
+       /**
+        * Return {@link Prompter} to be using
+        * 
+        * @return {@link Prompter} 
+        */
+       public
+       Prompter
+       getPrompter()
+       {
+               return this.prompter;
+       }
+       
+       /**
+        * Return {@link FileHandler} to be using
+        * 
+        * @return {@link FileHandler}
+        */
+       public
+       FileHandler
+       getFileHandler()
+       {
+               return this.fileHandler;
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/Executor.java b/org.tizen.common/src/org/tizen/common/core/command/Executor.java
new file mode 100644 (file)
index 0000000..6cd4e29
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Common
+ *
+ * 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.common.core.command;
+
+import static org.tizen.common.core.command.Policy.EXCEPTION_UNHANDLED;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.Factory;
+
+
+/**
+ * <p>
+ * Executor.
+ * 
+ * Execute command in specific environment
+ * 
+ * Environment is specified by {@link #contextFactory}
+ * 
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+Executor
+{
+       /**
+        * Logger for this instance
+        */
+       protected Logger logger = LoggerFactory.getLogger( getClass() );
+       
+       /**
+        * Factory for {@link ExecutionContext}
+        */
+       protected Factory<ExecutionContext> contextFactory;
+       
+       /**
+        * Cabinet for {@link ExecutionContext}
+        * 
+        * Context is sustain in execution and destroy after exection
+        * 
+        * @see #contextFactory
+        */
+       protected ThreadLocal<ExecutionContext> contexts = new ThreadLocal<ExecutionContext>()
+       {
+               /* (non-Javadoc)
+                * @see java.lang.ThreadLocal#initialValue()
+                */
+               @Override
+               protected
+               ExecutionContext
+               initialValue()
+               {
+                       if ( null == contextFactory )
+                       {
+                               return null;
+                       }
+                       return contextFactory.create();
+               };
+       };
+       
+       /**
+        * Default constructor
+        */
+       public
+       Executor()
+       {
+       }
+       
+       /**
+        * Constructor with context factory
+        * 
+        * @param factory context factory to use
+        * 
+        * @see #setContextFactory(Factory)
+        */
+       public
+       Executor(
+               final Factory<ExecutionContext> factory
+       )
+       {
+               setContextFactory( factory );
+       }
+       
+       /**
+        * Return context factory
+        * 
+        * @return context factory in use
+        */
+       public
+       Factory<ExecutionContext>
+       getContextFactory()
+       {
+               return this.contextFactory;
+       }
+       
+       /**
+        * Set context factory
+        * 
+        * @param factory context factory to use
+        */
+       public
+       void
+       setContextFactory(
+               final Factory<ExecutionContext> factory
+       )
+       {
+               logger.info( "ExecutionContextFactory :{}", factory );
+               this.contextFactory = factory;
+       }
+       
+       /**
+        * Execute <code>commands</code>
+        * 
+        * @param commands {@link Command}s
+        */
+       public
+       void
+       execute(
+               final Command<?>... commands
+       )
+       {
+        logger.trace( "Commands :{}", commands );
+        contexts.remove();
+        
+        execute( contexts.get(), commands );
+           
+       }
+       public
+       void
+       execute(
+               final ExecutionContext context,
+               final Command<?>... commands
+               )
+       {
+
+               try {
+                       for ( final Command<?> command : commands )
+                       {
+                               command.run( this, context );
+                       }
+               } catch ( final Exception e ) {
+                       final Policy policy = context.getPolicy( EXCEPTION_UNHANDLED );
+                       if ( null == policy )
+                       {       // No policy
+                               logger.error( "Error occured", e );
+                               return ;
+                       }
+                       
+                       final UncaughtExceptionHandler handler = policy.adapt( UncaughtExceptionHandler.class );
+                       if ( null == handler )
+                       {
+                               throw new IllegalStateException( e );
+                       }
+                       handler.uncaughtException( Thread.currentThread(), e );
+               }
+               finally
+               {
+               contexts.remove();
+               }
+       }
+       
+       /**
+        * Execute <code>command</code> in <code>context</code>
+        * 
+        * @param command {@link Command} to run
+        * @param context {@link ExecutionContext} to run in
+        */
+       public void
+       run(
+               final Command<?> command,
+               final ExecutionContext context
+       )
+       throws Exception
+       {
+               command.run( this, context );
+       }
+       
+       /**
+        * Return {@link ExecutionContext} in context
+        * 
+        * @return {@link ExecutionContext}
+        */
+       public ExecutionContext
+       getContext()
+       {
+               return contexts.get();
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/Policy.java b/org.tizen.common/src/org/tizen/common/core/command/Policy.java
new file mode 100644 (file)
index 0000000..479d2f3
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Common
+ *
+ * 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.common.core.command;
+
+import org.tizen.common.Adaptable;
+
+
+/**
+ * <p>
+ * Policy.
+ * 
+ * Adapter to other class when specific situation
+ * 
+ * Situation specification is defined by naming rule
+ * 
+ * Situation is define hierachically and is like tree structure
+ * 
+ * Situation name has qualified name separating dot( '.' ).
+ * 
+ * Each name fragment means node name in tree and qualified name stands for unique path.
+ * 
+ * If there is no matching policy in registry, it provide policy having least distance.
+ * 
+ * <ul>
+ *     <li>nonexist
+ *     <ul>
+ *             <li>file
+ *             <ul>
+ *                     <li>in</li>
+ *             </ul>
+ *             </li>
+ *             <li>dir
+ *             <ul>
+ *                     <li>in
+ *                     <ul>
+ *                             <li>project</li>
+ *                     </ul>
+ *                     </li>
+ *             </ul>
+ *             </li>
+ *     </ul>
+ *     </li>
+ *     <li>exist
+ *     <ul>
+ *             <li>file
+ *             <ul>
+ *                     <li>out
+ *                     <ul>
+ *                             <li>wgt</li>
+ *                     </ul>
+ *                     </li>
+ *             </ul>
+ *     </ul>
+ *     </li>
+ *     <li>exception
+ *     <ul>
+ *             <li>unhandled</li>
+ *             <li>file
+ *             <ul>
+ *                     <li>out
+ *                     <ul>
+ *                             <li>wgt</li>
+ *                     </ul>
+ *                     </li>
+ *             </ul>
+ *             </li>
+ *     </ul>
+ *     </li>
+ * </ul>
+ * 
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface
+Policy
+extends Adaptable
+{
+       /**
+        * When input file doesn't exist
+        */
+       String NONEXIST_IN_FILE = "nonexist.file.in";
+       
+       /**
+        * When input sign profile
+        */
+       String NONEXIST_IN_FILE_SIGN_PROFILE = "nonexist.file.in.signprofile";
+       
+       /**
+        * When input directory doesn't exist
+        */
+       String NONEXIST_IN_DIRECTORY = "nonexist.dir.in";
+       
+       /**
+        * When input project directory doesn't exist
+        */
+       String NONEXIST_IN_PROJECT = "nonexist.dir.in.project";
+       
+       /**
+        * When output file already exists
+        */
+       String EXIST_OUT_FILE = "exist.file.out";
+       /**
+        * When output widget file already exists
+        */
+       String EXIST_OUT_WGT = "exist.file.out.wgt";
+       
+       /**
+        * When target file is already exist.
+        */
+       String EXIST_FILE_WHEN_COPY = "exist.file.when.copy";
+       
+       /**
+        * When unexpected exception occured
+        */
+       String EXCEPTION_UNHANDLED = "exception.unhandled";
+       /**
+        * When exception occured in handling output widget file
+        */
+       String EXCEPTION_OUT_WGT = "exception.file.out.wgt";
+       
+       String PRINTOUT_RESULT_SIGNING = "printout.result.signing";
+       
+       /**
+        * Return policy name
+        * 
+        * policy name is unique indentifier
+        * 
+        * @return policy name
+        */
+       String getName();
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/PolicyRegistryFactory.java b/org.tizen.common/src/org/tizen/common/core/command/PolicyRegistryFactory.java
new file mode 100644 (file)
index 0000000..d055af0
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Web IDE - Command Line Interface
+ *
+ * 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.common.core.command;
+
+import static org.tizen.common.core.command.Policy.EXIST_OUT_FILE;
+import static org.tizen.common.core.command.Policy.NONEXIST_IN_FILE;
+import static org.tizen.common.core.command.Policy.EXIST_FILE_WHEN_COPY;
+import static org.tizen.common.core.command.Policy.EXCEPTION_UNHANDLED;
+import java.io.File;
+import org.tizen.common.Factory;
+import org.tizen.common.core.command.policy.AbstractPolicy;
+import org.tizen.common.core.command.policy.FilePolicy;
+import org.tizen.common.core.command.policy.MessagePolicy;
+import org.tizen.common.core.command.policy.OptionPolicy;
+import org.tizen.common.core.command.policy.PolicyRegistry;
+import org.tizen.common.core.command.policy.UncaughtExceptionHandlingPolicy;
+import org.tizen.common.core.command.prompter.RunableOption;
+import org.tizen.common.file.StandardFileHandler;
+
+/**
+ * <p>
+ * PolicyRegistryFactory.
+ * 
+ * {@link Factory} to provide {@link PolicyRegistry} in eclipse ide
+ * 
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+PolicyRegistryFactory
+implements Factory<PolicyRegistry>
+{
+       /**
+        * <p>
+        * CLIPolicy.
+        * 
+        * {@link Policy} when command line interface
+        * </p>
+        * 
+        * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+        * 
+        * @see PolicyRegistry, {@link Policy}
+        */
+       class EclipsePolicy 
+       extends AbstractPolicy
+       {
+               /**
+                * <p>
+                * Constructor with <code>name</code>
+                * </p>
+                * 
+                * @param name policy name
+                */
+               public EclipsePolicy( final String name )
+               {
+                       super( name );
+               }
+
+               /* (non-Javadoc)
+                * @see org.tizen.common.Adaptable#adapt(java.lang.Class)
+                */
+               @Override
+               @SuppressWarnings("unchecked")
+               public <T>
+               T
+               adapt(
+                       final Class<T> clazz
+               )
+               {
+                       if ( clazz.isAssignableFrom( FilePolicy.class ) )
+                       {
+                               return (T) FilePolicy.STOP_PROCESS;
+                       }
+                       else if ( clazz.isAssignableFrom( MessagePolicy.class) )
+                       {
+                               return (T) MessagePolicy.PROMPTER;
+                       }
+                       else if ( clazz.isAssignableFrom(UncaughtExceptionHandlingPolicy.class))
+                       {
+                               return (T) UncaughtExceptionHandlingPolicy.INSTANCE;
+                       }
+                       return null;
+               }
+
+       }
+       /* (non-Javadoc)
+        * @see org.tizen.common.Factory#create()
+        */
+       @Override
+       public
+       PolicyRegistry
+       create()
+       {
+               final PolicyRegistry registry = new PolicyRegistry();
+               
+               registry.register( new EclipsePolicy( EXIST_FILE_WHEN_COPY ) {
+                       @SuppressWarnings("unchecked")
+                       @Override
+                       public <T> T adapt(Class<T> clazz) {
+                               if(clazz.isAssignableFrom(OptionPolicy.class)) {
+                                       
+                                       RunableOption overwrite = new RunableOption("overwrite") {
+                                       
+                                       private StandardFileHandler handler = new StandardFileHandler();
+                                       
+                                       @Override
+                                       public void runWithArgument(Object... args) throws Exception {
+                                               if(args.length != 2) {
+                                                       throw new IllegalArgumentException("argument length is wrong");
+                                               }
+                                               
+                                               if(!(args[0] instanceof File && args[1] instanceof File)) {
+                                                       throw new IllegalArgumentException("argument type is wrong");
+                                               }
+                                               
+                                               File sourceFile = ((File)args[0]);
+                                               File targetFile = ((File)args[1]);
+                                               
+                                               handler.copyFile(sourceFile.getPath(), targetFile.getPath());
+                                       }
+                                       
+                                       @Override
+                                       public boolean isDefault() {
+                                               return false;
+                                       }
+                               };
+                               
+                               RunableOption ignore = new RunableOption("ignore") {
+                                       
+                                       @Override
+                                       public boolean isDefault() {
+                                               return true;
+                                       }
+                                       
+                                       @Override
+                                       protected void runWithArgument(Object... args) throws Exception{
+                                       }
+                               };
+                               
+                               RunableOption overwriteAll = new RunableOption("overwriteAll") {
+                                       
+                                       private StandardFileHandler handler = new StandardFileHandler();
+                                       
+                                       @Override
+                                       public boolean isDefault() {
+                                               return false;
+                                       }
+                                       
+                                       @Override
+                                       protected void runWithArgument(Object... args) throws Exception {
+                                               super.setAllFlag(true);
+                                               
+                                               if(args.length != 2) {
+                                                       throw new IllegalArgumentException("argument length is wrong");
+                                               }
+                                               
+                                               if(!(args[0] instanceof File && args[1] instanceof File)) {
+                                                       throw new IllegalArgumentException("argument type is wrong");
+                                               }
+                                               
+                                               File sourceFile = ((File)args[0]);
+                                               File targetFile = ((File)args[1]);
+                                               
+                                               handler.copyFile(sourceFile.getPath(), targetFile.getPath());
+                                       }
+                               };
+                               
+                               RunableOption ignoreAll = new RunableOption("ignoreAll") {
+                                       
+                                       @Override
+                                       public boolean isDefault() {
+                                               return false;
+                                       }
+                                       
+                                       @Override
+                                       protected void runWithArgument(Object... args) throws Exception{
+                                               super.setAllFlag(true);
+                                       }
+                               };
+                               
+                               RunableOption cancel = new RunableOption("cancel") {
+                                       
+                                       @Override
+                                       public boolean isDefault() {
+                                               return false;
+                                       }
+                                       
+                                       @Override
+                                       protected void runWithArgument(Object... args) throws Exception{
+                                       }
+                               };
+                                       
+                                       return (T)(new OptionPolicy(overwrite, ignore, overwriteAll, ignoreAll, cancel));
+                               }
+                               return super.adapt(clazz);
+                       }
+               });
+               
+               registry.register(new EclipsePolicy(EXCEPTION_UNHANDLED) {
+                       
+                       @SuppressWarnings("unchecked")
+                       @Override
+                       public <T> T adapt(Class<T> clazz) {
+                               if ( clazz.isAssignableFrom(UncaughtExceptionHandlingPolicy.class))
+                               {
+                                       return (T) UncaughtExceptionHandlingPolicy.INSTANCE;
+                               }
+                               return null;
+                       }
+               });
+               registry.register( new EclipsePolicy(EXIST_OUT_FILE));
+               registry.register( new EclipsePolicy( NONEXIST_IN_FILE ) );
+               
+               return registry;
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/Prompter.java b/org.tizen.common/src/org/tizen/common/core/command/Prompter.java
new file mode 100644 (file)
index 0000000..a76752b
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Common
+ *
+ * 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.common.core.command;
+
+import org.tizen.common.core.command.prompter.Option;
+
+/**
+ * <p>
+ * Prompter.
+ * 
+ * Handle user interaction
+ * <ul>
+ *     <li>user input</li>
+ *     <li>message output</li>
+ * <ul>
+ * 
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface
+Prompter
+{
+       /**
+        * <p>
+        * Input user selection.
+        * 
+        * The selection must be in <code>options</code>
+        * </p>
+        * 
+        * @param question selection message
+        * @param options options to choice
+        * 
+        * @return user selection
+        */
+       Option interact( final String question, final Option... options );
+
+       /**
+        * <p>
+        * Input user input as password
+        * 
+        * Password must be secured
+        * </p>
+        * 
+        * @param message message for user password
+        * 
+        * @return user input as password
+        */
+       char[] password( String message );
+
+       /**<p>
+        * Print out error message
+        * </p>
+        * 
+        * @param message error message
+        */
+       void error( final String message );
+
+       /**
+        * Print out information message to notify
+        * 
+        * @param message notification message
+        */
+       void notify( final String message );
+
+       /**
+        * User cancle work in process
+        */
+       void cancel();
+
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/file/DirectoryCopyHandlingCommand.java b/org.tizen.common/src/org/tizen/common/core/command/file/DirectoryCopyHandlingCommand.java
new file mode 100644 (file)
index 0000000..d1ea1f6
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Ho Namkoong <ho.namkoong@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.common.core.command.file;
+
+import java.io.File;
+import java.util.List;
+import java.util.Stack;
+
+import org.tizen.common.core.command.AbstractCommand;
+import org.tizen.common.core.command.CommandCancelException;
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.core.command.Policy;
+import org.tizen.common.core.command.policy.OptionPolicy;
+import org.tizen.common.core.command.prompter.Option;
+import org.tizen.common.core.command.prompter.RunableOption;
+import org.tizen.common.file.StandardFileHandler;
+import org.tizen.common.util.log.Logger;
+
+/**
+ * <p>
+ * DirectoryCopyHandlingCommand.
+ * This class is used for copying source directory to the target directory.
+ * {@link FileHandlingCommand}
+ * </p>
+ * 
+ * @author Ho Namkoong{@literal <ho.namkoong@samsung.com>} (S-Core)
+ */
+
+public class DirectoryCopyHandlingCommand extends FileHandlingCommand<Boolean> {
+    
+    /**
+     * List of target path
+     */
+    protected List<String> targetPathList;
+    
+    /**
+     * List of source path
+     */
+    protected List<String> sourcePathList;
+    
+    public DirectoryCopyHandlingCommand(List<String> sourcePathList, List<String> targetPathList) throws IllegalArgumentException{
+        if(sourcePathList.size() != targetPathList.size()) {
+            throw new IllegalArgumentException("Lenghs of sourcePathList and target paths are not same");
+        }
+        this.sourcePathList = sourcePathList;
+        this.targetPathList = targetPathList;
+    }
+    
+    
+    @Override
+    public void run(Executor executor, ExecutionContext context)
+            throws Exception {
+        StandardFileHandler handler = new StandardFileHandler();
+        Policy policy = context.getPolicy(Policy.EXIST_FILE_WHEN_COPY);
+        OptionPolicy optionPolicy = policy.adapt( OptionPolicy.class );
+        Option[] options = optionPolicy.getOptions();
+        
+        for(Option option: options) {
+            if(!(option instanceof RunableOption)) {
+                throw new IllegalArgumentException("Option " + option.getName() + " is not RunnableOption");
+            }
+        }
+        
+        for(int i =0; i< sourcePathList.size(); i++) {
+            String sourcePath = sourcePathList.get(i);
+            String targetPath = targetPathList.get(i);
+            
+            final Stack<File> sourceStack = new Stack<File>();
+            final Stack<File> targetStack = new Stack<File>();
+            sourceStack.push( new File(sourcePath ) );
+            targetStack.push( new File( targetPath ) );
+            
+            while ( !sourceStack.isEmpty() )
+            {
+                final File sourceFile = sourceStack.pop();
+                final File targetFile = targetStack.pop();
+                
+                if ( sourceFile.isDirectory() )
+                {
+                    handler.makeDirectory(targetFile.getPath());
+                    for ( final File sourceChild : sourceFile.listFiles() )
+                    {
+                        sourceStack.push( sourceChild );
+                        targetStack.push( new File( targetFile, sourceChild.getName() ) );
+                    }
+                }
+                else if(sourceFile.isFile()) {
+                    if(targetFile.exists()) {
+                        boolean selectionDone = false;
+                        RunableOption resultOption = null;
+                        
+                        for (Option option : options) {
+                            if(((RunableOption)option).isAllFlag()) {
+                                resultOption = (RunableOption)option;
+                                selectionDone = true;
+                                break;
+                            }
+                        }
+                        
+                        if(!selectionDone) {
+                            resultOption = (RunableOption)context.getPrompter().interact(targetFile.getCanonicalPath() + " already exist", options);
+                        }
+                        if(AbstractCommand.COMMAND_CANCEL.equals(resultOption.getName())) {
+                            throw new CommandCancelException();
+                        }
+                        
+                        resultOption.setArgument(sourceFile, targetFile);
+                        resultOption.run();
+                    }
+                    else {
+                        System.out.println(targetFile);
+                        targetFile.createNewFile();
+                        handler.copyFile(sourceFile.getPath(), targetFile.getPath());
+                    }
+                }
+                else {
+                    Logger.error(sourceFile + " is not file or directory");
+                }
+            }
+        }
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/file/FileHandlingCommand.java b/org.tizen.common/src/org/tizen/common/core/command/file/FileHandlingCommand.java
new file mode 100644 (file)
index 0000000..78f079e
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.file;
+
+import org.tizen.common.FactoryWithArgument;
+import org.tizen.common.core.command.AbstractCommand;
+import org.tizen.common.core.command.Command;
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.file.Filter;
+import org.tizen.common.file.SimpleFileFilter;
+import org.tizen.common.file.filter.WildCardFilterFactory;
+
+/**
+ * FileHandlingCommand.
+ * 
+ * Abstract class for file handling {@link Command}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+FileHandlingCommand<T>
+extends AbstractCommand<T>
+{
+       /**
+        * Factory to create file name pattern filter
+        */
+       protected FactoryWithArgument<Filter, String> filterFactory = new WildCardFilterFactory();
+       
+       /**
+        * File name filter
+        */
+       protected SimpleFileFilter filter = new SimpleFileFilter();
+       
+       /**
+        * Handling main path
+        */
+       protected String path;
+       
+       /**
+        * Set filter factory
+        * 
+        * @param factory {@link FactoryWithArgument<Filter, String>}
+        * 
+        * @see WildCardFilterFactory
+        */
+       public
+       void
+       setFilterFactory(
+               final FactoryWithArgument<Filter, String> factory
+       )
+       {
+               this.filterFactory = factory;
+               logger.debug( "Configured filter factory :{}", factory );
+       }
+       
+       /**
+        * Set filter
+        * @param filter {@link SimpleFileFilter}
+        */
+       public
+       void
+       setFilter( SimpleFileFilter filter )
+       {
+               if ( null == filter )
+               {
+                       throw new NullPointerException();
+               }
+               this.filter = filter;
+               logger.debug( "Configured filter :{}", filter );
+       }
+       
+       /**
+        * Set including file name patterns
+        * 
+        * @param includes including file name patterns
+        */
+       public
+       void
+       setIncludes(
+               final String[] includes
+       )
+       {
+               filter.clearIncludes();
+               if ( null != includes )
+               {
+                       for ( final String include : includes )
+                       {
+                               filter.addIncludes( filterFactory.create( include ) );
+                       }
+               }
+       }
+       
+       /**
+        * Set excluding file name patterns
+        * 
+        * @param excludes excluding file name patterns
+        */
+       public
+       void
+       setExcludes(
+               final String[] excludes
+       )
+       {
+               filter.clearExcludes();
+               if ( null != excludes )
+               {
+                       for ( final String exclude : excludes )
+                       {
+                               filter.addExcludes( filterFactory.create( exclude ) );
+                       }
+               }
+       }
+
+       /**
+        * Return main working path
+        * 
+        * @return {@link #path}
+        */
+       public
+       String
+       getPath()
+       {
+               return this.path;
+       }
+       
+       /**
+        * Set main working path
+        * 
+        * @param path main working path
+        */
+       public
+       void
+       setPath(
+               final String path
+       )
+       {
+               this.path = path;
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.AbstractCommand#execute(org.tizen.common.core.command.Executor, org.tizen.common.core.command.ExecutionContext)
+        */
+       @Override
+       public
+       void
+       run(
+               final Executor executor,
+               final ExecutionContext context
+       )
+       throws Exception
+       {
+               throw new UnsupportedOperationException();
+               
+       }
+       
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.AbstractCommand#undo(org.tizen.common.core.command.Executor, org.tizen.common.core.command.ExecutionContext)
+        */
+       @Override
+       public
+       void
+       undo(
+               final Executor executor,
+               final ExecutionContext context
+       )
+       throws Exception {
+               throw new UnsupportedOperationException();
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/file/WriteFileCommand.java b/org.tizen.common/src/org/tizen/common/core/command/file/WriteFileCommand.java
new file mode 100644 (file)
index 0000000..9b60e18
--- /dev/null
@@ -0,0 +1,40 @@
+package org.tizen.common.core.command.file;
+
+import java.io.ByteArrayInputStream;
+
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.util.ObjectUtil;
+
+public class
+WriteFileCommand
+extends FileHandlingCommand<Boolean>
+{
+       protected final byte[] contents;
+       
+       public WriteFileCommand( final String path, final byte[] contents )
+       {
+               setPath( path );
+               this.contents = contents; 
+       }
+       
+       @Override
+       public
+       void
+       run(
+               final Executor executor,
+               final ExecutionContext context
+       )
+       throws Exception
+       {
+           final byte[] safeBytes = ObjectUtil.nvl( contents, new byte[0] );
+           
+           logger.trace( "Trying write {} in {} bytes", path, safeBytes.length );
+           
+           context.getFileHandler().write(
+               path,
+               new ByteArrayInputStream( safeBytes )
+           );
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/policy/AbstractMessagePolicy.java b/org.tizen.common/src/org/tizen/common/core/command/policy/AbstractMessagePolicy.java
new file mode 100644 (file)
index 0000000..1c1ca76
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.policy;
+
+import static org.tizen.common.util.StringUtil.NULL_STRING;
+
+import java.text.MessageFormat;
+
+/**
+ * AbstractMessagePolicy.
+ * 
+ * Abstract class for {@link MessagePolicy}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+abstract public class
+AbstractMessagePolicy
+implements MessagePolicy
+{
+
+       /**
+        * Provide common formatting rule
+        * 
+        * @param format message format
+        * @param args message arguments
+        * 
+        * @return formatted message
+        */
+       protected
+       String
+       format(
+               final String format,
+               final Object... args
+       )
+       {
+               if ( null == format )
+               {
+                       return NULL_STRING;
+               }
+               return MessageFormat.format( format, args );
+               
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/policy/AbstractPolicy.java b/org.tizen.common/src/org/tizen/common/core/command/policy/AbstractPolicy.java
new file mode 100644 (file)
index 0000000..25b12a5
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.policy;
+
+import org.tizen.common.core.command.Policy;
+
+/**
+ * AbstractPolicy.
+ * 
+ * Abstract class for {@link Policy}
+ * 
+ * All policy must have name and can't change it
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+abstract public class
+AbstractPolicy
+implements Policy
+{
+       
+       /**
+        * Policy name
+        */
+       protected final String name;
+       
+       /**
+        * Constructor with policy name
+        * 
+        * @param name poclicy name
+        * 
+        * @see Policy
+        */
+       public
+       AbstractPolicy(
+               final String name
+       )
+       {
+               this.name = name;
+       }
+       
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Policy#getName()
+        */
+       @Override
+       public
+       String
+       getName()
+       {
+               return this.name;
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/policy/FilePolicy.java b/org.tizen.common/src/org/tizen/common/core/command/policy/FilePolicy.java
new file mode 100644 (file)
index 0000000..d70487f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.policy;
+
+
+/**
+ * FilePolicy.
+ * 
+ * File handling policy
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public enum
+FilePolicy
+{
+       /**
+        * <p>
+        * Stop process.
+        * 
+        * Throw exception
+        * </p>
+        */
+       STOP_PROCESS,
+       
+       /**
+        * <p>
+        * Skip process.
+        * 
+        * Don't throw exception
+        * </p>
+        */
+       SKIP,
+       
+       /**
+        * <p>
+        * overwwrite when already exist
+        * </p>
+        */
+       OVERWRITE,
+       
+       /**
+        * <p>
+        * Make directory when directory doesn't exist
+        * </p>
+        */
+       MAKE_DIR,
+       
+       /**
+        * <p>
+        * Make file when file doesn't exist
+        * </p>
+        */
+       MAKE_FILE
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/policy/MessagePolicy.java b/org.tizen.common/src/org/tizen/common/core/command/policy/MessagePolicy.java
new file mode 100644 (file)
index 0000000..379c601
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.policy;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.core.command.Prompter;
+
+/**
+ * FilePolicy.
+ * 
+ * File handling policy
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface
+MessagePolicy
+{
+       /**
+        * Print out message
+        * 
+        * @param prompter {@link Prompter}
+        * @param format message format
+        * @param args message arguments
+        */
+       void
+       print(
+               final Prompter prompter,
+               final String format,
+               final Object... args
+       );
+       
+       /**
+        * Print out error message
+        * @param prompter {@link Prompter}
+        * @param format message format
+        * @param args message arguments
+        */
+       void
+       error(
+               final Prompter prompter,
+               final String format,
+               final Object... args
+       );
+       
+       /**
+        * {@link MessagePolicy} to print out using logger
+        * 
+        * FIXME caller fqcn is constants
+        */
+       MessagePolicy LOGGING = new AbstractMessagePolicy()
+       {
+               /**
+                * Logger to use for message printing
+                */
+               protected final Logger logger =
+                       LoggerFactory.getLogger( getClass() );
+
+               /* (non-Javadoc)
+                * @see org.tizen.common.core.command.policy.MessagePolicy#print(org.tizen.common.core.command.Prompter, java.lang.String, java.lang.Object[])
+                */
+               @Override
+               public
+               void
+               print(
+                       final Prompter prompter,
+                       final String format,
+                       final Object... args
+               )
+               {
+                       logger.debug( format( format, args ) );
+               }
+
+               /* (non-Javadoc)
+                * @see org.tizen.common.core.command.policy.MessagePolicy#error(org.tizen.common.core.command.Prompter, java.lang.String, java.lang.Object[])
+                */
+               @Override
+               public void error(
+                       final Prompter prompter,
+                       final String format,
+                       final Object... args
+               )
+               {
+                       logger.error( format( format, args ) );
+               }
+       };
+       
+       /**
+        * {@link MessagePolicy} to print out using {@link Prompter}
+        */
+       MessagePolicy PROMPTER = new AbstractMessagePolicy()
+       {
+               
+               /* (non-Javadoc)
+                * @see org.tizen.common.core.command.policy.MessagePolicy#print(org.tizen.common.core.command.Prompter, java.lang.String, java.lang.Object[])
+                */
+               @Override
+               public
+               void
+               print(
+                       final Prompter prompter,
+                       final String format,
+                       final Object... args
+               )
+               {
+                       prompter.notify( format( format, args ) );
+               }
+
+               /* (non-Javadoc)
+                * @see org.tizen.common.core.command.policy.MessagePolicy#error(org.tizen.common.core.command.Prompter, java.lang.String, java.lang.Object[])
+                */
+               @Override
+               public void error(
+                       final Prompter prompter,
+                       final String format,
+                       final Object... args
+               )
+               {
+                       prompter.error( format( format, args ) );
+                       
+               }
+       };
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/policy/OptionPolicy.java b/org.tizen.common/src/org/tizen/common/core/command/policy/OptionPolicy.java
new file mode 100644 (file)
index 0000000..df6e482
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Ho Namkoong <ho.namkoong@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.common.core.command.policy;
+
+import org.tizen.common.core.command.prompter.Option;
+
+/**
+ * OptionPolicy
+ * This policy returns options which are needed for Prompt#interact(final String question, final Option... options).
+ * @See Command, Prompter
+ * @author Changhyun Lee {@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+
+public class OptionPolicy  {
+    
+    protected Option[] options;
+    
+    /**
+     * <p>
+     * Constructor with <code>options</code>
+     * </p>
+     * 
+     * @param options options which this policy will return.
+     */
+    public OptionPolicy(Option... options) {
+        this.options = options;
+    }
+    
+    /**
+     * Returns options this policy has.
+     * 
+     * @return return options.
+     */
+    public Option[] getOptions() {
+        return options;
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/policy/PolicyRegistry.java b/org.tizen.common/src/org/tizen/common/core/command/policy/PolicyRegistry.java
new file mode 100644 (file)
index 0000000..0308d6a
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.policy;
+
+import java.util.HashMap;
+
+import org.tizen.common.core.command.Policy;
+import org.tizen.common.util.StringUtil;
+
+
+/**
+ * <p>
+ * PolicyRegistry.
+ * 
+ * Registry for {@link Policy}
+ * 
+ * {@link Policy} is stored in tree-like structure
+ * 
+ * A node has {@link Policy} or doesn't
+ * 
+ * A node has multiple child nodes
+ * 
+ * Policy's location is made a decision by its name
+ * 
+ * name is composed of subname and separator( "<b>.</b>" )
+ * 
+ * example for name is following
+ * <ul>
+ * <li>invalid.input.format.file</li>
+ * <li>nonexist.input.file</li>
+ * <li>exist.output.file</li>
+ * </ul>
+ * </p>
+ * @author bylee
+ *
+ */
+public class PolicyRegistry
+{
+       /**
+        * Node.
+        * 
+        * Node for tree structure
+        * 
+        * @author bylee
+        *
+        */
+       class Node
+       {
+               
+               /**
+                * {@link Policy} stored in node
+                */
+               protected Policy policy;
+               
+               /**
+                * Default constructor
+                */
+               public Node()
+               {
+               }
+               
+               /**
+                * Constructor with {@link Policy}
+                * 
+                * @param policy {@link Policy} to store
+                */
+               public Node(
+                       final Policy policy
+               )
+               {
+                       this.policy = policy;
+               }
+               
+               protected final HashMap<String, Node> name2child =
+                       new HashMap<String, PolicyRegistry.Node>();
+               
+               /**
+                * Rerturn {@link Policy} to be stored
+                * 
+                * @return policy to be stored
+                */
+               public Policy getPolicy()
+               {
+                       return this.policy;
+               }
+               
+               /**
+                * Set policy
+                *
+                * @param policy {@link Policy} to store
+                */
+               public void setPolicy(
+                       final Policy policy
+               )
+               {
+                       this.policy = policy;
+               }
+               
+               
+               /**
+                * Get child node with <code>name</code> in this node
+                * 
+                * @param name node's name
+                * 
+                * @return child node with <code>name</code>
+                */
+               public Node getChild(
+                       final String name
+               )
+               {
+                       return name2child.get( name );
+               }
+               
+               /**
+                * Add <code>node</code> with <code>name</code> as child
+                * 
+                * @param name node name
+                * @param node node to add
+                */
+               public void addChild( final String name, Node node )
+               {
+                       name2child.put( name, node );
+               }
+       }
+       
+       /**
+        * No-operation policy. Missing object pattern
+        */
+       protected Policy noOp = new AbstractPolicy( "" )
+       {
+               /* (non-Javadoc)
+                * @see org.tizen.common.Adaptable#adapt(java.lang.Class)
+                */
+               @Override
+               public <T> T adapt( final Class<T> clazz )
+               {
+                       return null;
+               }
+       };
+       
+       /**
+        * Root node( in tree structure)
+        */
+       protected Node root = new Node();
+       
+       /**
+        * Constructor with {@link Policy}s
+        * 
+        * @param policies {@link Policy}s to add
+        * 
+        * @see #register(Policy)
+        */
+       public
+       PolicyRegistry(
+               final Policy... policies
+       )
+       {
+               if ( null == policies )
+               {
+                       return ;
+               }
+               
+               register( policies );
+       }
+       
+       /**
+        * Add <code>policies</code> to registry
+        * 
+        * @param policies {@link Policy}s to add
+        */
+       public void
+       register(
+               final Policy... policies
+       )
+       {
+               for ( final Policy policy : policies )
+               {
+                       final String name = policy.getName();
+                       
+                       final Node node = createNode( name );
+                       
+                       if ( null != node.getPolicy() )
+                       {
+                               throw new IllegalArgumentException( "Policy is duplicated" );
+                       }
+                       
+                       node.setPolicy( policy );
+               }
+               
+       }
+       
+       /**
+        * Create node with <code>path</code> in tree
+        * 
+        * @param path node path from root in tree
+        * 
+        * @return {@link Node} to be specified with <code>path</code>
+        */
+       public Node createNode( final String path )
+       {
+               final String[] fragments = StringUtil.split( path, "." );
+               
+               Node iter = root;
+               
+               for ( int i = 0, n = fragments.length ; i < n ; ++i )
+               {
+                       Node child = iter.getChild( fragments[i] );
+                       if ( null == child )
+                       {
+                               child = new Node();
+                               iter.addChild( fragments[i], child );
+                       }
+                       
+                       iter = child;
+               }
+               
+               return iter;
+       }
+       
+       /**
+        * Return {@link Policy} from tree with <code>path</code>
+        * 
+        * Return ancestor node's policy unless matching exactly
+        * 
+        * @param path
+        * 
+        * @return {@link Policy}
+        */
+       public Policy
+       getPolicy( final String path )
+       {
+               if ( StringUtil.isEmpty( path ) )
+               {
+                       return noOp;
+               }
+               final String[] fragments = StringUtil.split( path, "." );
+               
+               Node iter = root;
+               
+               Policy policy = null;
+               
+               for ( int i = 0, n = fragments.length ; i < n ; ++i )
+               {
+                       if ( null != iter.getPolicy() )
+                       {
+                               policy = iter.getPolicy();
+                       }
+                       
+                       Node child = iter.getChild( fragments[i] );
+                       if ( null == child )
+                       {
+                               return policy;
+                       }
+                       iter = child;
+               }
+               
+               if ( null == iter.getPolicy() )
+               {
+                       return policy;
+               }
+               return iter.getPolicy();
+       }
+       
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public String toString()
+       {
+           return getClass().getSimpleName() + "@" + Integer.toHexString( hashCode() ).substring( 0, 4 );
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/policy/SimplePolicy.java b/org.tizen.common/src/org/tizen/common/core/command/policy/SimplePolicy.java
new file mode 100644 (file)
index 0000000..d0f7638
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.policy;
+
+import org.tizen.common.core.command.Policy;
+
+public class SimplePolicy
+implements Policy {
+
+    protected String name;
+    
+    public SimplePolicy( final String name )
+    {
+        this.name = name;
+    }
+    @Override
+    public <T> T adapt(Class<T> clazz) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/policy/UncaughtExceptionHandlingPolicy.java b/org.tizen.common/src/org/tizen/common/core/command/policy/UncaughtExceptionHandlingPolicy.java
new file mode 100644 (file)
index 0000000..f16f9c7
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Ho Namkoong <ho.namkoong@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.common.core.command.policy;
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.tizen.common.core.command.CommandCancelException;
+import org.tizen.common.util.log.Logger;
+
+/**
+ * UncaughtExceptionHandlingPolicy.
+ * 
+ * Exception handling policy
+ * Singleton class implemented using enum
+ * 
+ * @author Ho Namkoong{@literal <ho.namkoong@samsung.com>} (S-Core)
+ */
+public enum UncaughtExceptionHandlingPolicy
+        implements
+            UncaughtExceptionHandler {
+    
+    /**
+     * singleton instance.
+     */
+    INSTANCE();
+
+    /**
+     * map which stores handler (value) according to the throwable class name (name).
+     */
+    private final Map<String, UncaughtExceptionHandler> repository = new HashMap<String, UncaughtExceptionHandler>();
+    
+    /**
+     * get handler from repository, and handle exception.
+     * If appropriate repository is not found, 
+     * it searches for handler which handles superclass of target exception.
+     * 
+     * @param t current thread
+     * @param e exception which should be handled
+     * @since 1.5
+     */
+    @Override
+    public void uncaughtException(Thread t, Throwable e) {
+        
+        UncaughtExceptionHandler handler = null;
+        Class<? extends Object> throwableClass = e.getClass();
+        
+        do {
+            handler = repository.get(throwableClass.getCanonicalName());
+            if(handler != null) {
+                handler.uncaughtException(t, e);
+                return;
+            }
+            
+            throwableClass = throwableClass.getSuperclass();
+        } while (!throwableClass.getCanonicalName().equals(Object.class.getCanonicalName()));
+        
+        throw new IllegalStateException(e);
+    }
+    
+    private UncaughtExceptionHandlingPolicy() {
+        installUncaughtExceptionHandlers();
+    }
+    
+    private void installUncaughtExceptionHandlers() {
+        
+        //Install OperationCancelException Handler
+        this.putHandler(CommandCancelException.class.getCanonicalName(), new UncaughtExceptionHandler() {
+            @Override
+            public void uncaughtException(Thread t, Throwable e) {
+                if(e instanceof CommandCancelException) {
+                    throw (CommandCancelException)e;
+                }
+                else {
+                    throw new IllegalStateException();
+                }
+            }
+        });
+    }
+
+    private void putHandler(String throwableName, UncaughtExceptionHandler handler) {
+        if(repository.containsKey(throwableName)) {
+            if(!repository.get(throwableName).equals(handler)) {
+                Logger.error("Handlers are duplicate assigned with one key: " + throwableName);
+            }
+            return;
+        }
+        repository.put(throwableName, handler);
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/prompter/AbstractOption.java b/org.tizen.common/src/org/tizen/common/core/command/prompter/AbstractOption.java
new file mode 100644 (file)
index 0000000..d60b177
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import static org.tizen.common.util.StringUtil.isEmpty;
+import static org.tizen.common.util.StringUtil.trim;
+
+import org.tizen.common.util.ObjectUtil;
+
+/**
+ * <p>
+ * AbstractOption.
+ * 
+ * Abstract(common) class for option
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+AbstractOption
+implements Option
+{
+       /**
+        * <p>
+        * Option name
+        * 
+        * It is printed out
+        * </p>
+        */
+       protected final String name;
+
+       /**
+        * Flag if user input is handled as abbreviation
+        */
+       protected final boolean bPermitAbbreviation;
+
+       /**
+        * Flag if this option is default( choice when user doesn't select option )
+        */
+       protected final boolean bDefault;
+
+       /**
+        * Constructor with choice name, default flag and abbreviation flag
+        * 
+        * @param name choice name
+        * @param bDefault default flag
+        * @param bPermitAbbreviation abbreviation flag
+        */
+       public
+       AbstractOption(
+               final String name,
+               final boolean bDefault,
+               final boolean bPermitAbbreviation
+       )
+       {
+               this.name = trim( name );
+
+               this.bDefault = bDefault;
+
+               this.bPermitAbbreviation = bPermitAbbreviation;
+       }
+
+       /**
+        * Return option name
+        * 
+        * @return option name
+        */
+       public String getName()
+       {
+               return this.name;
+       }
+
+       /**
+        * Return whether this choice is default {@link ChoiceOption}
+        * 
+        * @return boolean value if this choice is default
+        */
+       public boolean isDefault()
+       {
+               return this.bDefault;
+       }
+
+       /**
+        * Return whether user input, <code>value</code> is match option
+        * 
+        * @param value user input
+        * 
+        * @return boolean value If matching
+        */
+       public
+       boolean
+       isMatch(
+               final String value
+       )
+       {
+               if ( name.equalsIgnoreCase( trim( value ) ) )
+               {
+                       return true;
+               }
+
+               if ( isEmpty( value ) )
+               {
+                       return false;
+               }
+               if ( bPermitAbbreviation )
+               {
+                       return name.substring( 0, 1 ).equalsIgnoreCase( value.substring( 0, 1 ) );
+               }
+
+               return false;
+
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#hashCode()
+        */
+       @Override
+       public
+       int
+       hashCode()
+       {
+               return name.hashCode();
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       @Override
+       public
+       boolean
+       equals(
+               final Object obj
+       )
+       {
+               if ( !( obj instanceof ChoiceOption ) )
+               {
+                       return false;
+               }
+               final ChoiceOption other = (ChoiceOption) obj;
+               return ObjectUtil.equals( this.name, other.name );
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public
+       String
+       toString()
+       {
+               if ( isDefault() )
+               {
+                       return "[" + name + "]";
+               }
+               return name;
+       }
+
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/prompter/AbstractPrompter.java b/org.tizen.common/src/org/tizen/common/core/command/prompter/AbstractPrompter.java
new file mode 100644 (file)
index 0000000..701a977
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.core.command.Prompter;
+
+/**
+ * AbstractPrompter.
+ * 
+ * Abstract class for sub class for {@link Prompter}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+AbstractPrompter
+{
+       
+       /**
+        * Logger for this instance
+        */
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+
+       protected
+       void
+       checkOptions( ChoiceOption[] options )
+       {
+               if ( null == options )
+               {
+                       throw new NullPointerException(); 
+               }
+               
+               final HashSet<Option> reducedOptions = new LinkedHashSet<Option>();
+               Option defaultOption = null;
+               final ArrayList<String> optionNames = new ArrayList<String>();
+               for ( final Option option : options )
+               {
+                       if ( reducedOptions.contains( option ) )
+                       {
+                               throw new IllegalArgumentException(
+                                       "Question can't have duplicated choice(s) :" + option 
+                               );
+                       }
+                       optionNames.add( option.getName() );
+                       reducedOptions.add( option );
+                       if ( option.isDefault() )
+                       {
+                               if ( null != defaultOption )
+                               {
+                                       throw new IllegalArgumentException(
+                                               "Question must have only one default choice"
+                                       );
+                               }
+                                       
+                               defaultOption = option;
+                       }
+               }
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/prompter/ChoiceOption.java b/org.tizen.common/src/org/tizen/common/core/command/prompter/ChoiceOption.java
new file mode 100644 (file)
index 0000000..267941b
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import static org.tizen.common.util.StringUtil.hasText;
+
+import org.tizen.common.util.Assert;
+
+/**
+ * <p>
+ * Option.
+ * 
+ * Option to choice
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+ChoiceOption
+extends AbstractOption
+{
+       /**
+        * Constructor with choice name
+        * 
+        * @param name choice name
+        * 
+        * #see {@link #Option(String, boolean)}
+        */
+       public
+       ChoiceOption(
+               final String name
+       )
+       {
+               this( name, false );
+       }
+       
+       /**
+        * Constructor with choice name and default flag
+        * 
+        * @param name choice name
+        * @param bDefault default flag
+        * 
+        * @see #Option(String, boolean, boolean)
+        */
+       public
+       ChoiceOption(
+               final String name,
+               final boolean bDefault
+       )
+       {
+               this( name, bDefault, true );
+       }
+
+       /**
+        * Constructor with choice name, default flag and abbreviation flag
+        * 
+        * @param name choice name
+        * @param bDefault default flag
+        * @param bPermitAbbreviation abbreviation flag
+        */
+       public
+       ChoiceOption(
+               final String name,
+               final boolean bDefault,
+               final boolean bPermitAbbreviation
+       )
+       {
+               super( name, bDefault, bPermitAbbreviation );
+               Assert.isTrue( hasText( name ) );
+       }
+       
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/prompter/EclipsePrompter.java b/org.tizen.common/src/org/tizen/common/core/command/prompter/EclipsePrompter.java
new file mode 100644 (file)
index 0000000..cb4f3e6
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import java.util.HashMap;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.core.command.Prompter;
+import org.tizen.common.util.ObjectUtil;
+import org.tizen.common.util.StringUtil;
+
+/**
+ * <p>
+ * EclipsePrompter.
+ * 
+ * Context aware prompter using extension
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+EclipsePrompter
+implements Prompter
+{
+       protected static final String EP_ID = "org.tizen.common.prompter";
+       
+       protected static final String ATTR_SCOPE = "scope";
+       
+       protected static final String ATTR_CLASS = "class";
+                       
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+       
+       /**
+        * Default prompter
+        */
+       protected final Prompter defaultPrompter;
+       
+       protected final HashMap<String, Prompter> name2prompter;
+
+       /**
+        * Constructor with default prompter
+        * 
+        * @param defaultPrompter {@link Prompter}
+        */
+       public EclipsePrompter(
+               final Prompter defaultPrompter
+       )
+       {
+               this.defaultPrompter = defaultPrompter;
+               this.name2prompter = new HashMap<String, Prompter>();
+       }
+       
+       protected Prompter
+       getPrompter()
+       {
+               final StackTraceElement[] stacks = Thread.currentThread().getStackTrace();
+               
+               final IExtensionRegistry registry = Platform.getExtensionRegistry();
+               final IExtensionPoint ep = registry.getExtensionPoint( EP_ID );
+               final IExtension[] exts = ep.getExtensions();
+               
+               for ( final StackTraceElement stack : stacks )
+               {
+                       final String className = stack.getClassName();
+                       
+                       for ( final IExtension ext : exts )
+                       {
+                               final IConfigurationElement[] configs = ext.getConfigurationElements();
+                               for  ( IConfigurationElement config : configs )
+                               {
+                                       final String scope = config.getAttribute( ATTR_SCOPE );
+                                       if ( StringUtil.isEmpty( scope ) ) 
+                                       {
+                                               continue;
+                                       }
+
+                                       if ( !ObjectUtil.equals( className, scope ) )
+                                       {
+                                               continue;
+                                       }
+
+                                       try {
+                                               return (Prompter) config.createExecutableExtension( ATTR_CLASS );
+                                       } catch ( CoreException e )
+                                       {
+                                               logger.error( "Can't create prompter :" + config.getAttribute( ATTR_CLASS ) );
+                                               return defaultPrompter;
+                                       }
+                               }
+                       }
+               }
+               
+               return defaultPrompter;
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#interact(java.lang.String, org.tizen.common.core.command.prompter.Option[])
+        */
+       @Override
+       public Option interact(
+               final String question,
+               final Option... options
+       )
+       {
+               final Prompter prompter = getPrompter();
+               return prompter.interact(question, options);
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#password(java.lang.String)
+        */
+       @Override
+       public
+       char[] password(
+               final String message
+       )
+       {
+               final Prompter prompter = getPrompter();
+               return prompter.password(message);
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#error(java.lang.String)
+        */
+       @Override
+       public
+       void
+       error(
+               final String message
+       )
+       {
+               final Prompter prompter = getPrompter();
+               prompter.error(message);
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#notify(java.lang.String)
+        */
+       @Override
+       public
+       void
+       notify(
+               final String message
+       )
+       {
+               final Prompter prompter = getPrompter();
+               prompter.notify(message);
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#cancel()
+        */
+       @Override
+       public
+       void
+       cancel()
+       {
+               final Prompter prompter = getPrompter();
+               prompter.cancel();
+       }
+
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public String toString()
+       {
+           return getClass().getSimpleName() + "@" + Integer.toHexString( hashCode() ).substring( 0, 4 );
+       }
+       
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/prompter/GenericOption.java b/org.tizen.common/src/org/tizen/common/core/command/prompter/GenericOption.java
new file mode 100644 (file)
index 0000000..003b35b
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import static org.tizen.common.util.StringUtil.hasText;
+
+import org.tizen.common.util.Assert;
+
+/**
+ * <p>
+ * GenericOption.
+ * 
+ * {@link ChoiceOption} for general input
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+GenericOption
+extends AbstractOption
+{
+       
+       /**
+        * User input
+        */
+       protected String answer;
+
+       /**
+        * Default constructor
+        */
+       public
+       GenericOption()
+       {
+               super( "", false, false );
+       }
+
+       /**
+        * Constructor with choice name
+        * 
+        * @param name choice name
+        * 
+        * #see {@link #Option(String, boolean)}
+        */
+       public
+       GenericOption(final String name)
+       {
+           super( name, false, false );
+           this.answer = name;
+       }
+
+       /**
+        * Constructor with choice name and default flag
+        * 
+        * @param name choice name
+        * @param bDefault default flag
+        * 
+        * @see #Option(String, boolean, boolean)
+        */
+       public
+       GenericOption (
+               final String name,
+               final boolean bDefault
+               )
+       {
+           super( name, bDefault, false );
+           this.answer = name;
+       }
+
+       /**
+        * Constructor with choice name, default flag and abbreviation flag
+        * 
+        * @param name choice name
+        * @param bDefault default flag
+        * @param bPermitAbbreviation abbreviation flag
+        */
+       public
+       GenericOption (
+               final String name,
+               final boolean bDefault,
+               final boolean bPermitAbbreviation
+               )
+       {
+           super( name, bDefault, bPermitAbbreviation );
+           Assert.isTrue( hasText( name ) );
+           this.answer = name;
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.prompter.AbstractOption#isMatch(java.lang.String)
+        */
+       @Override
+       public
+       boolean
+       isMatch(
+               final String value
+       )
+       {
+               this.answer = value;
+               return true;
+       }
+
+       /**
+        * Return user input
+        * 
+        * @return user input
+        */
+       public String
+       getAnswer()
+       {
+               return this.answer;
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public
+       String
+       toString()
+       {
+           if ( isDefault() )
+           {
+               return "[" + this.answer + "]";
+           }
+           return this.answer;
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/prompter/NopPrompter.java b/org.tizen.common/src/org/tizen/common/core/command/prompter/NopPrompter.java
new file mode 100644 (file)
index 0000000..c202a35
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import org.tizen.common.core.command.Prompter;
+
+/**
+ * <p>
+ * NopPrompter.
+ * 
+ * No-Operation Prompter doesn't interact with human
+ * 
+ * It is used for batch process or test
+ * 
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+NopPrompter
+extends AbstractPrompter
+implements Prompter
+{
+       
+       protected char[] password;
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#interact(java.lang.String, int, org.tizen.common.core.command.prompter.Option[])
+        */
+       public
+       Option
+       interact(
+               final String question,
+               final Option... options
+       )
+       {
+               for ( Option option : options )
+               {
+                       if ( option.isDefault() )
+                       {
+                               return option;
+                       }
+               }
+               throw new IllegalArgumentException();
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#notify(java.lang.String, java.lang.Object[])
+        */
+       @Override
+       public
+       void
+       notify(
+               final String message
+       )
+       {
+               logger.info( "Notification >>> {}", message );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#cancel()
+        */
+       @Override
+       public void cancel()
+       {
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#password(java.lang.String)
+        */
+       @Override
+       public
+       char[] password(
+               final String message
+       )
+       {
+               return password;
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#error(java.lang.String, java.lang.Object[])
+        */
+       @Override
+       public
+       void
+       error(
+               final String message
+       )
+       {
+               logger.error( "Error >>> {}", message );
+       }
+       
+       /**
+        * Set password
+        * 
+        * @param password password to be provided automatically
+        */
+       public
+       void
+       setPassword(
+               final char[] password
+       )
+       {
+               this.password = password;
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/prompter/Option.java b/org.tizen.common/src/org/tizen/common/core/command/prompter/Option.java
new file mode 100644 (file)
index 0000000..c2c624c
--- /dev/null
@@ -0,0 +1,11 @@
+package org.tizen.common.core.command.prompter;
+
+public interface Option
+{
+       String getName();
+
+       boolean isDefault();
+
+       boolean isMatch( final String value );
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/prompter/RunableOption.java b/org.tizen.common/src/org/tizen/common/core/command/prompter/RunableOption.java
new file mode 100644 (file)
index 0000000..dc78fe7
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * Ho Namkoong <ho.namkoong@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.common.core.command.prompter;
+
+public abstract class RunableOption implements Option{
+    
+    /**
+     * Arguments which will be used in run.
+     */
+    private Object[] args;
+    
+    /**
+     * if true, remaning selection is following this option
+     * For example, if you select ignore all or overwrite all when deuplicate files are found, then this flag becomes true.
+     */
+    private boolean allFlag = false;
+    
+    /**
+     * name of this option
+     */
+    private String name;
+    
+    /**
+     * Constructor with name
+     * 
+     * @param name name of this operation
+     */
+    public RunableOption(String name) {
+        this.name = name;
+        this.args = null;
+    }
+    
+    /**
+     * Constructor with name and arguments
+     * 
+     * @param name name of this operation
+     * @param args arguments of this operation
+     */
+    public RunableOption(String name, Object... args) {
+        this.name = name;
+        this.args = args;
+    }
+    
+    /**
+     * Set arguments
+     * 
+     * @param args arguments of this operation
+     */
+    public void setArgument(Object... args) {
+        this.args = args;
+    }
+    
+    /**
+     * Set all flag
+     * 
+     * @param allFlag all flag of this operation
+     */
+    protected void setAllFlag(boolean allFlag) {
+        this.allFlag = allFlag;
+    }
+
+    /**
+     * return all flag
+     * 
+     * @return return true if all flag is true, else return false
+     */
+    public boolean isAllFlag() {
+        return allFlag;
+    }
+    
+    /**
+     * return name
+     * 
+     * @return return name of this operation
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+    
+    /**
+     * Check if name of this operation and value are matched.
+     * 
+     * @arg value value which is compared with name of this operation
+     * @return return true if matched, else return false.
+     */
+    @Override
+    public boolean isMatch(String value) {
+        if(this.getName().equals(value)) {
+            return true;
+        }
+        return false;
+    }
+
+    protected abstract void runWithArgument(Object... args) throws Exception;
+    
+    public void run() throws Exception {
+        this.runWithArgument(args);
+    }
+    
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/prompter/SWTPrompter.java b/org.tizen.common/src/org/tizen/common/core/command/prompter/SWTPrompter.java
new file mode 100755 (executable)
index 0000000..ca29bff
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import static org.tizen.common.util.SWTUtil.asyncExec;
+import static org.tizen.common.util.SWTUtil.exec;
+import static org.tizen.common.util.SWTUtil.getActiveShell;
+import static org.tizen.common.util.SWTUtil.syncExec;
+import static org.tizen.common.util.StringUtil.trim;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.tizen.common.core.command.Prompter;
+import org.tizen.common.ui.dialog.PasswordInputDialog;
+import org.tizen.common.util.NotificationType;
+import org.tizen.common.util.NotifierDialog;
+import org.tizen.common.util.SWTRunner;
+
+/**
+ * <p>
+ * SWTPrompter.
+ * 
+ * {@link Prompter} in SWT environment
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+SWTPrompter
+extends AbstractPrompter
+implements Prompter
+{
+       
+       /**
+        * Create dialog for user interaction
+        * 
+        * @param question message for dialog
+        * @param optionNames option names for dialog
+        * @param defaultOptionIndex initial selection for option
+        * 
+        * @return {@link Dialog} for user selection
+        */
+       protected
+       Dialog
+       createDialog(
+               final String question,
+               final String[] optionNames,
+               final int defaultOptionIndex
+       )
+       {
+               return new MessageDialog(
+                       getActiveShell(),
+                       "Question",
+                       null,
+                       question,
+                       MessageDialog.QUESTION,
+                       optionNames,
+                       defaultOptionIndex
+               )
+               {
+                       protected void buttonPressed( int buttonId )
+                       {
+                               setReturnCode( buttonId );
+                               close();
+                       }
+               };
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#interact(java.lang.String, org.tizen.common.core.command.prompter.Option[])
+        */
+       @Override
+       public
+       Option
+       interact(
+               final String question,
+               final Option... options
+       )
+       {
+               final HashSet<Option> reducedOptions = new LinkedHashSet<Option>();
+               Option defaultOption = null;
+               final ArrayList<String> optionNames = new ArrayList<String>();
+               for ( final Option option : options )
+               {
+                       if ( reducedOptions.contains( option ) )
+                       {
+                               throw new IllegalArgumentException(
+                                       "Question can't have duplicated choice(s) :" + option
+                               );
+                       }
+                       optionNames.add( option.getName() );
+                       reducedOptions.add( option );
+                       if ( option.isDefault() )
+                       {
+                               if ( null != defaultOption )
+                               {
+                                       throw new IllegalArgumentException(
+                                               "Question must have only one default choice"
+                                       );
+                               }
+                                       
+                               defaultOption = option;
+                       }
+               }
+               final int defaultIndex = optionNames.indexOf( defaultOption.getName() );
+               
+               return exec( new SWTRunner<Option>()
+        {
+                   /* (non-Javadoc)
+                    * @see org.tizen.common.util.SWTRunner#process()
+                    */
+                   public Option process() {
+                       final Dialog dialog = createDialog( question, optionNames.toArray( new String[0] ), defaultIndex );
+                       dialog.open();
+                       return options[dialog.getReturnCode()];
+                   }
+               } );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#notify(java.lang.String, java.lang.Object[])
+        */
+       @Override
+       public void
+       notify(
+               final String message
+       )
+       {
+               asyncExec( new Runnable() {
+                       
+                       /* (non-Javadoc)
+                        * @see java.lang.Runnable#run()
+                        */
+                       @Override
+                       public void run() {
+                               NotifierDialog.notify( "Notify", message, NotificationType.INFO );
+                       }
+               } );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#cancel()
+        */
+       @Override
+       public void cancel() {
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#password(java.lang.String)
+        */
+       @Override
+       public
+       char[] password(
+               final String message
+       )
+       {
+               return exec( new SWTRunner<char[]>()
+        {
+                       /* (non-Javadoc)
+                        * @see java.lang.Runnable#run()
+                        */
+                       @Override
+                       public char[] process()
+                       {
+                           final PasswordInputDialog dialog =
+                               new PasswordInputDialog( "Password Input Dialog", message );
+                           
+                               dialog.open();
+                               
+                               if ( IDialogConstants.OK_ID != dialog.getReturnCode() )
+                               {
+                                   return null;
+                               }
+                               
+                               return trim( dialog.getValue() ).toCharArray();
+                       }
+               } );
+               
+               
+               
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.Prompter#error(java.lang.String, java.lang.Object[])
+        */
+       @Override
+       public
+       void
+       error(
+               final String message
+       )
+       {
+               syncExec( new Runnable() {
+                       
+                       /* (non-Javadoc)
+                        * @see java.lang.Runnable#run()
+                        */
+                       @Override
+                       public void run() {
+                               MessageDialog.openError( getActiveShell(), "Error", message );
+                       }
+               } );
+                       
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/sdb/DevicesSdbCommand.java b/org.tizen.common/src/org/tizen/common/core/command/sdb/DevicesSdbCommand.java
new file mode 100644 (file)
index 0000000..e86d38d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.util.Assert;
+import org.tizen.sdblib.IDevice;
+
+public class DevicesSdbCommand
+extends SdbHandlingCommand
+{
+    protected SmartDevelopmentBridgeManager createBridge()
+    {
+        return new SmartDevelopmentBridgeManager();
+    }
+
+    @Override
+    public void run( final Executor executor, ExecutionContext context)
+    {
+        SmartDevelopmentBridgeManager bridge = createBridge();
+        Assert.notNull( bridge );
+
+        IDevice devices[] = bridge.getDevices();
+        String result = new String();
+        for ( IDevice device : devices )
+        {
+            result += device.toString() + System.getProperty("line.separator");
+        }
+        setResult( result );
+
+        context.getPrompter().notify( getResult() );
+    }
+
+    @Override
+    public void undo(final Executor executor, ExecutionContext context) throws Exception
+    {
+        // TODO Auto-generated method stub
+        
+    }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/sdb/DlogSdbCommand.java b/org.tizen.common/src/org/tizen/common/core/command/sdb/DlogSdbCommand.java
new file mode 100644 (file)
index 0000000..f4bfb88
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+
+public class DlogSdbCommand
+extends ShellSdbCommand
+{
+    protected String DLOG_COMMAND = "dlogutil";
+
+    public void setFilter(String filter) {
+        this.DLOG_COMMAND = "dlogutil "+filter;
+    }
+
+    @Override
+    public void run(Executor executor, ExecutionContext context)
+            throws Exception {
+        setCommand( this.DLOG_COMMAND );
+        super.run( executor, context );
+    }
+
+    @Override
+    public void undo(Executor executor, ExecutionContext context)
+            throws Exception {
+        // TODO Auto-generated method stub
+        
+    }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/sdb/ForwardSdbCommand.java b/org.tizen.common/src/org/tizen/common/core/command/sdb/ForwardSdbCommand.java
new file mode 100644 (file)
index 0000000..11540d8
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.util.Assert;
+import org.tizen.sdblib.IDevice;
+
+public class ForwardSdbCommand
+extends SdbDevicesHandlingCommand
+{
+    private int localPort;
+    private int remotePort;
+
+    public ForwardSdbCommand(int localPort, int remotePort) {
+        this.localPort = localPort;
+        this.remotePort = remotePort;
+    }
+
+    @Override
+    public void run(final Executor executor, ExecutionContext context) throws InterruptedException {
+        IDevice device = getDevice();
+        Assert.notNull( device );
+
+        try {
+            device.createForward( localPort, remotePort );
+        }  catch (Exception e) {
+            // TODO Message fix need
+            context.getPrompter().notify( "forward socket connections error" );
+        }
+    }
+
+    @Override
+    public void undo(Executor executor, ExecutionContext context)
+            throws Exception {
+        IDevice device = getDevice();
+        Assert.notNull( device );
+
+        try {
+            device.removeForward( localPort, remotePort );
+        }  catch (Exception e) {
+            // TODO Message fix need
+            context.getPrompter().notify( "remove forward socket connections error" );
+        }
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/sdb/PullSdbCommand.java b/org.tizen.common/src/org/tizen/common/core/command/sdb/PullSdbCommand.java
new file mode 100644 (file)
index 0000000..9257298
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import java.io.IOException;
+
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.util.Assert;
+import org.tizen.sdblib.IDevice;
+import org.tizen.sdblib.SdbCommandRejectedException;
+import org.tizen.sdblib.SyncService;
+import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
+import org.tizen.sdblib.SyncService.SyncResult;
+import org.tizen.sdblib.TimeoutException;
+
+public class PullSdbCommand
+extends SdbDevicesHandlingCommand
+{
+    protected String remotePath;
+    protected String localPath;
+
+    public PullSdbCommand(String remotePath, String localPath)
+    {
+        this.remotePath = remotePath;
+        this.localPath = localPath;
+    }
+
+    protected SyncService getSyncService() throws TimeoutException, SdbCommandRejectedException, IOException
+    {
+        return device.getSyncService();
+    }
+
+    protected ISyncProgressMonitor getProgressMonitor() {
+        return SyncService.getNullProgressMonitor();
+    }
+
+    @Override
+    public void run(final Executor executor, ExecutionContext context)
+    throws Exception
+    {
+        IDevice device = getDevice();
+        Assert.notNull( device );
+
+        try
+        {
+            SyncService service = getSyncService();
+            SyncResult syncSuccess = 
+                    service.pullFile( remotePath, localPath, getProgressMonitor() );
+            if ( syncSuccess.getCode() != SyncService.RESULT_OK ) {
+                // TODO Message fix need
+                context.getPrompter().notify( "transfer error" );
+            }
+        } catch (Exception e) {
+            throw new IllegalStateException( e );
+        }
+    }
+
+    @Override
+    public void undo(final Executor executor, ExecutionContext context) throws Exception {
+        // TODO Auto-generated method stub
+        
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/sdb/PushSdbCommand.java b/org.tizen.common/src/org/tizen/common/core/command/sdb/PushSdbCommand.java
new file mode 100644 (file)
index 0000000..46db4c4
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import java.io.IOException;
+
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.util.Assert;
+import org.tizen.common.util.FilenameUtil;
+import org.tizen.sdblib.IDevice;
+import org.tizen.sdblib.SdbCommandRejectedException;
+import org.tizen.sdblib.SyncService;
+import org.tizen.sdblib.SyncService.ISyncProgressMonitor;
+import org.tizen.sdblib.SyncService.SyncResult;
+import org.tizen.sdblib.TimeoutException;
+
+public class PushSdbCommand
+extends SdbDevicesHandlingCommand
+{
+    protected String localPath;
+    protected String remotePath;
+
+    public PushSdbCommand(String localPath, String remotePath)
+    {
+        this.localPath = localPath;
+        this.remotePath = remotePath;
+    }
+
+    protected SyncService getSyncService() throws TimeoutException, SdbCommandRejectedException, IOException
+    {
+        return device.getSyncService();
+    }
+
+    protected ISyncProgressMonitor getProgressMonitor() {
+        return SyncService.getNullProgressMonitor();
+    }
+
+    @Override
+    public void run(final Executor executor, ExecutionContext context)
+    throws Exception
+    {
+        IDevice device = getDevice();
+        Assert.notNull( device );
+
+        try
+        {
+            SyncService service = getSyncService();
+            SyncResult syncSuccess = 
+                    service.pushFile( localPath, remotePath, getProgressMonitor() );
+            String name = FilenameUtil.getFilename( localPath );
+            if ( syncSuccess.getCode() != SyncService.RESULT_OK ) {
+                setResult( "failed" );
+                context.getPrompter().notify( name + " file transfer failed" );
+                return ;
+            }
+            setResult( "success" );
+            context.getPrompter().notify( name + " file transfer success" );
+        } catch (Exception e) {
+            throw new IllegalStateException( e );
+        }
+    }
+
+    @Override
+    public void undo(final Executor executor, ExecutionContext context) throws Exception {
+        // TODO Auto-generated method stub
+        
+    }
+
+}
@@ -1,44 +1,45 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-\r
-\r
-public class DefaultTreeModel extends AbstractTreeModel {\r
-\r
-       public DefaultTreeModel(ITreeVO source){\r
-               super(source);\r
-       }\r
-\r
-       public String getSourceName() {\r
-               String str = this.source.getClass().getSimpleName();\r
-               if(str.endsWith("VO")) //$NON-NLS-1$\r
-                       str = str.substring(0,str.length()-2);\r
-               return str;\r
-       }\r
-}\r
-\r
-\r
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import org.tizen.sdblib.IDevice;
+
+public abstract class
+SdbDevicesHandlingCommand
+extends SdbHandlingCommand
+{
+    protected IDevice device;
+
+    public void setDevice(IDevice device)
+    {
+        this.device = device;
+    }
+
+    public IDevice getDevice()
+    {
+        return this.device;
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/sdb/SdbHandlingCommand.java b/org.tizen.common/src/org/tizen/common/core/command/sdb/SdbHandlingCommand.java
new file mode 100644 (file)
index 0000000..6c98a72
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import org.tizen.common.core.command.Command;
+
+public abstract class
+SdbHandlingCommand
+implements Command<String>
+{
+    protected StringBuffer result;
+
+    public void clearResult() {
+        if ( this.result == null ) {
+            this.result = new StringBuffer();
+        } else {
+            this.result.delete( 0, result.capacity() );
+            this.result.setLength( 0 );
+        }
+    }
+
+    public String getResult()
+    {
+        if ( this.result == null ) {
+            return null;
+        }
+        return this.result.toString();
+    }
+
+    public void setResult(String result)
+    {
+        if ( this.result == null ) {
+            this.result = new StringBuffer();
+        }
+        this.result.append( result );
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/sdb/ShellSdbCommand.java b/org.tizen.common/src/org/tizen/common/core/command/sdb/ShellSdbCommand.java
new file mode 100644 (file)
index 0000000..5efc22f
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.util.Assert;
+import org.tizen.sdblib.IDevice;
+import org.tizen.sdblib.MultiLineReceiver;
+
+/**
+ * <p>
+ * ShellSdbCommand.
+ * 
+ * Command to run shell in target
+ * </p>
+ * 
+ * @author GyeongSeok Seo{@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class ShellSdbCommand
+extends SdbDevicesHandlingCommand
+{
+    private String command;
+    private static int DEFAULT_TIME = 90;
+
+    /**
+     * Wait for shell command completion
+     */
+    private int time;
+
+    /**
+     * Get wait for shell command completion time
+     * 
+     * @return time value
+     */
+    public int getTime() {
+        return time;
+    }
+
+    /**
+     * Set wait for shell command completion time
+     * 
+     * @param time value
+     */
+    public void setTime(int time) {
+        this.time = time <= 0 ? DEFAULT_TIME : time;
+    }
+
+    /**
+     * Constructor, default command is empty so if using this constructor then must call setCommand
+     */
+    public ShellSdbCommand() {
+        this.time = DEFAULT_TIME;
+    }
+
+    /**
+     * Constructor with command, command is running in target device.
+     * 
+     * @param command
+     */
+    public ShellSdbCommand(String command) {
+        this.command = command;
+        this.time = DEFAULT_TIME;
+    }
+
+    /**
+     * Get command, command is running in target device
+     * 
+     * @return command
+     */
+    public String getCommand() {
+        return command;
+    }
+
+    /**
+     * Set command, command is running in target device
+     * 
+     * @param command
+     */
+    public void setCommand(String command) {
+        this.command = command;
+    }
+
+    /**
+     * Create MultiLineReceiver, MultiLineReceiver's processNewLines method save command running result
+     * 
+     * @return MultiLineReceiver
+     */
+    public MultiLineReceiver createMultiLineReceiver() {
+        return new MultiLineReceiver() {
+            @Override
+            public void processNewLines(String[] lines) {
+                for( String content: lines ) {
+                    setResult( content+System.getProperty( "line.separator" ) );
+                }
+            }
+        };
+    }
+
+    @Override
+    public void run(Executor executor, ExecutionContext context)
+            throws Exception {
+        IDevice device = getDevice();
+        Assert.notNull( device );
+        Assert.notNull( command );
+
+        clearResult();
+        device.executeShellCommand( command, createMultiLineReceiver(), getTime()*1000 );
+    }
+
+    @Override
+    public void undo(Executor executor, ExecutionContext context)
+            throws Exception {
+        // TODO Auto-generated method stub
+        
+    }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/sdb/SmartDevelopmentBridgeManager.java b/org.tizen.common/src/org/tizen/common/core/command/sdb/SmartDevelopmentBridgeManager.java
new file mode 100644 (file)
index 0000000..66a5bb9
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import org.tizen.sdblib.IDevice;
+import org.tizen.sdblib.SmartDevelopmentBridge;
+
+/**
+ * <p>
+ * SmartDevelopmentBridgeManager.
+ * 
+ * class for delegate SmartDevelopmentBridge.
+ * 
+ * </p>
+ * 
+ * @author GyeongSeok Seo{@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class SmartDevelopmentBridgeManager
+{
+    private SmartDevelopmentBridge impl = SmartDevelopmentBridge.getBridge();
+
+    public boolean equals(Object obj) {
+        return impl.equals(obj);
+    }
+
+    public int getConnectionAttemptCount() {
+        return impl.getConnectionAttemptCount();
+    }
+
+    public IDevice[] getDevices() {
+        return impl.getDevices();
+    }
+
+    public int getRestartAttemptCount() {
+        return impl.getRestartAttemptCount();
+    }
+
+    public String getSdbOsLocation() {
+        return impl.getSdbOsLocation();
+    }
+
+    public boolean hasInitialDeviceList() {
+        return impl.hasInitialDeviceList();
+    }
+
+    public int hashCode() {
+        return impl.hashCode();
+    }
+
+    public boolean isConnected() {
+        return impl.isConnected();
+    }
+
+    public boolean restart() {
+        return impl.restart();
+    }
+
+    public String toString() {
+        return impl.toString();
+    }
+
+    public void disconnectBridge() {
+        impl.disconnectBridge();
+    }
+
+    public void terminate() {
+        impl.terminate();
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/core/command/zip/ZipCommand.java b/org.tizen.common/src/org/tizen/common/core/command/zip/ZipCommand.java
new file mode 100644 (file)
index 0000000..639349f
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.zip;
+
+import static org.tizen.common.core.command.Policy.EXIST_OUT_WGT;
+import static org.tizen.common.core.command.Policy.NONEXIST_IN_DIRECTORY;
+import static org.tizen.common.util.FilenameUtil.getRelativePath;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.core.command.Policy;
+import org.tizen.common.core.command.file.FileHandlingCommand;
+import org.tizen.common.core.command.policy.FilePolicy;
+import org.tizen.common.core.command.policy.MessagePolicy;
+import org.tizen.common.file.FileHandler;
+import org.tizen.common.file.FileHandler.Attribute;
+import org.tizen.common.file.FileHandler.Type;
+import org.tizen.common.util.Assert;
+import org.tizen.common.util.FilenameUtil;
+import org.tizen.common.util.IOUtil;
+
+/**
+ * <p>
+ * ZipCommand.
+ * 
+ * Command to make zip archive
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+ZipCommand
+extends FileHandlingCommand<Object>
+{
+       /**
+        * Directory to zip
+        */
+       protected final String baseDir;
+       
+       /**
+        * Constructor with base dir and target file name
+        * 
+        * @param baseDir base directory path
+        * @param target target file name
+        */
+       public
+       ZipCommand(
+               final String baseDir,
+               final String target
+       )
+       {
+               this.baseDir = baseDir;
+               setPath( target );
+       }
+       
+       /* (non-Javadoc)
+        * @see org.tizen.common.core.command.file.FileHandlingCommand#execute(org.tizen.common.core.command.Executor, org.tizen.common.core.command.ExecutionContext)
+        */
+       @Override
+       public
+       void
+       run(
+               final Executor executor,
+               final ExecutionContext context
+       )
+       throws IOException, InterruptedException
+       {
+               final FileHandler handler = context.getFileHandler();
+               Assert.notNull( handler );
+               
+               if ( !handler.is( baseDir, Attribute.EXISTS ) )
+               {
+                       final Policy policy = context.getPolicy( NONEXIST_IN_DIRECTORY );
+                       
+                       final MessagePolicy messagePolicy = policy.adapt( MessagePolicy.class );
+                       
+                       messagePolicy.print( context.getPrompter(), "{0} doesn't exist", baseDir );
+                       return ;
+               }
+               
+               if ( handler.is( path, Attribute.EXISTS ) )
+               {
+                       final Policy policy = context.getPolicy( EXIST_OUT_WGT );
+                       
+                       final MessagePolicy messagePolicy = policy.adapt( MessagePolicy.class );
+                       messagePolicy.print( context.getPrompter(), "Widget already exists" );
+                       
+                       final FilePolicy filePolicy = policy.adapt( FilePolicy.class );
+                       
+                       if ( FilePolicy.OVERWRITE.equals( filePolicy ) )
+                       {
+                               // No op
+                       }
+                       else
+                       {       // It is default to stop process
+                               return ;
+                       }
+                       
+               }
+               
+               final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+               final ZipOutputStream zipOut = new ZipOutputStream( byteOut );
+
+               try
+               {
+                       final Queue<String> directories = new LinkedList<String>();
+                       
+                       directories.add( baseDir );
+                       
+                       while ( !directories.isEmpty() )
+                       {
+                               final String filePath = directories.remove();
+                               final Object type = handler.get( filePath, Attribute.TYPE );
+                               
+                               logger.trace( "File path :{}", filePath );
+                               
+                               if (
+                                       !FilenameUtil.equals( filePath, baseDir ) &&
+                                       !filter.accept( baseDir, FilenameUtil.getRelativePath( baseDir, filePath ) )
+                               )
+                               {
+                                       logger.debug( "Ignore {}", filePath );
+                                       continue;
+                               }
+                               logger.trace( "file [{}]'s type :{}", filePath, type );
+                               if ( Type.DIRECTORY.equals( type ) )
+                               {
+                                       final Collection<String> childs = handler.list( filePath );
+                                       directories.addAll( childs );
+                               }
+                               else if ( Type.FILE.equals( type ) )
+                               {
+                                       final String relative = getRelativePath( baseDir, filePath );
+                                       final ZipEntry entry = new ZipEntry( relative );
+                                       zipOut.putNextEntry( entry );
+                                       IOUtil.redirect( handler.read( filePath ), zipOut );
+                                       logger.debug( "Zip {}", relative );
+                               }
+                       }
+                       try {
+                               handler.write( path, new ByteArrayInputStream( byteOut.toByteArray() ) );
+                               context.getPrompter().notify( MessageFormat.format( "Widget[{0}] is created successfully ", path ) );
+                       }
+                       catch ( IOException e )
+                       {
+                               throw new IllegalStateException( e );
+                               // TODO Handle
+                       }
+               }
+               catch( IOException e )
+               {
+                       
+                       // TODO Handle
+               }
+               finally
+               {
+                       tryClose( zipOut );
+               }
+               
+               
+       }
+       
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/AbstractFileHandler.java b/org.tizen.common/src/org/tizen/common/file/AbstractFileHandler.java
new file mode 100644 (file)
index 0000000..c25d7cf
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * AbstractFileHandler.
+ *
+ * Abstract class for {@link FileHandler}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+abstract public class
+AbstractFileHandler
+implements FileHandler
+{
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+       
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#is(java.lang.String, org.tizen.common.file.FileHandler.Attribute)
+        */
+       @Override
+       public boolean is(
+               final String path,
+               final Attribute name
+       )
+       throws IOException
+       {
+               final Object obj = get( path, name );
+               if ( obj instanceof Boolean )
+               {
+                       return (Boolean) obj;
+               }
+               return false;
+       }
+
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/EclipseFileHandler.java b/org.tizen.common/src/org/tizen/common/file/EclipseFileHandler.java
new file mode 100644 (file)
index 0000000..5e98ad4
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+import static org.tizen.common.util.CollectionUtil.concatenate;
+import static org.tizen.common.util.CollectionUtil.removeLast;
+import static org.tizen.common.util.FilenameUtil.getCanonicalForm;
+import static org.tizen.common.util.FilenameUtil.getRelativePath;
+import static org.tizen.common.util.FilenameUtil.isAncestor;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Queue;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.tizen.common.util.FilenameUtil;
+import org.tizen.common.util.ObjectUtil;
+
+/**
+ * <p>
+ * EclipseFileHandler.
+ * 
+ * {@link FileHandler} for eclipse plugin
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+EclipseFileHandler
+extends StandardFileHandler
+{
+
+       /**
+        * @return
+        */
+       protected
+       IWorkspaceRoot
+       getWorkspace()
+       {
+               return ResourcesPlugin.getWorkspace().getRoot();
+       }
+       
+       protected IResource getFile( final String path ) throws IOException
+       {
+               final String root = getWorkspace().getLocation().toPortableString();
+               logger.trace( "Path :{}, Root :{}", path, root );
+               
+               final File fileChecker = new File( path );
+               String relativePath = path;
+               if ( isAncestor( root, path ) )
+               {
+                       relativePath = getRelativePath( root, path );
+               }
+               else if ( fileChecker.isAbsolute() )
+               {
+                       return null;
+               }
+
+               final Queue<String> fragments =
+                       new LinkedList<String>( Arrays.asList( FilenameUtil.getCanonicalFragments( relativePath ) ) );
+               
+               final String projectName =  fragments.remove();
+               if ( ".metadata".equals( projectName ) )
+               {
+                       return null;
+               }
+               final IProject project = getWorkspace().getProject( projectName );
+               if ( fragments.isEmpty() )
+               {
+                       return project;
+               }
+               
+               final String fileName = removeLast( fragments );
+               
+               IContainer parent = project;
+               if ( !fragments.isEmpty() )
+               {
+                       parent = project.getFolder( concatenate( fragments, "/" ) );
+               }
+               
+               try {
+                       final IResource[] children = parent.members();
+                       for ( final IResource chlid : children )
+                       {
+                               if ( ObjectUtil.equals( fileName, chlid.getName() ) )
+                               {
+                                       return chlid;
+                               }
+                       }
+                       fragments.add( fileName );
+                       final String relativeFile = concatenate( fragments, "/" );
+                       return project.getFile( relativeFile );
+               } catch (
+                       CoreException e
+               )
+               {
+                       logger.warn( "Exception :{}", e );
+               }
+               return null;
+       }
+       
+       protected IContainer getFolder( final String path )
+       {
+               final String root = getWorkspace().getLocation().toPortableString();
+               logger.trace( "Path :{}, Root :{}", path, root );
+               final File fileChecker = new File( path );
+               String relativePath = path;
+               if ( isAncestor( root, path ) )
+               {
+                       relativePath = getRelativePath( root, path );
+               }
+               else if ( fileChecker.isAbsolute() )
+               {
+                       return null;
+               }
+
+               final Queue<String> fragments =
+                       new LinkedList<String>( Arrays.asList( FilenameUtil.getCanonicalFragments( relativePath ) ) );
+
+               final String projectName = fragments.remove();
+               if ( ".metadata".equals( projectName ) )
+               {
+                       return null;
+               }
+               final IProject project = getWorkspace().getProject( projectName );
+               if ( fragments.isEmpty() )
+               {
+                       return project;
+               }
+               
+               final String fileName = removeLast( fragments );
+               
+               IContainer parent = project;
+               if ( !fragments.isEmpty() )
+               {
+                       parent = project.getFolder( concatenate( fragments, "/" ) );
+               }
+               
+               try {
+                       final IResource[] children = parent.members();
+                       for ( final IResource chlid : children )
+                       {
+                               if ( ObjectUtil.equals( fileName, chlid.getName() ) )
+                               {
+                                       return (IContainer) chlid;
+                               }
+                       }
+                       fragments.add( fileName );
+                       final String relativeFile = concatenate( fragments, "/" );
+                       return project.getFolder( relativeFile );
+               } catch (
+                       CoreException e
+               )
+               {
+               }
+               return null;
+
+       }
+       
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#getCurrentWorkingDirectory()
+        */
+       @Override
+       public
+       String
+       getCurrentWorkingDirectory()
+       {
+               return getWorkspace().getLocation().toPortableString();
+       }
+       
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#setCurrentWorkingDirectory(java.lang.String)
+        */
+       @Override
+       public
+       void
+       setCurrentWorkingDirectory(
+               final String cwd
+       )
+       {
+               throw new UnsupportedOperationException();
+
+       }
+
+       @Override
+       public
+       void
+       makeDirectory(
+               final String path
+       )
+       throws IOException
+       {
+               final File file = new File( path );
+               if ( file.isAbsolute() )
+               {
+                       super.makeDirectory( path );
+                       final Path p = new Path( path );
+                       try {
+                               getWorkspace().getFileForLocation( p ).refreshLocal( -1, new NullProgressMonitor() );
+                       } catch ( final CoreException e )
+                       {
+                               throw new IOException( e );
+                       }
+               }
+               
+       }
+
+       @Override
+       public
+       void
+       moveDirectory(
+               final String source,
+               final String target
+       )
+       throws IOException
+       {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public void copyDirectory(String source, String target) throws IOException {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public void removeDirectory(String path) throws IOException {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public
+       Collection<String>
+       list(
+               final String path
+       )
+       throws IOException
+       {
+
+               final IContainer folder = getFolder( path );
+               if ( null == folder )
+               {
+                       return super.list( path );
+               }
+               try {
+                       final IResource[] children = folder.members();
+                       final ArrayList<String> ret = new ArrayList<String>();
+                       
+                       for ( final IResource child : children )
+                       {
+                               
+                               String childPath = getCanonicalForm( child.getLocation().toPortableString() );
+                               
+                               if ( child instanceof IContainer )
+                               {
+                                       childPath = childPath + "/";
+                               }
+                               
+                               if ( childPath.startsWith( "/" ) )
+                               {
+                                       ret.add( childPath.substring( 1 ) );
+                               }
+                               else
+                               {
+                                       ret.add( childPath );
+                               }
+                       }
+                       
+                       logger.trace( "Children :{}", ret );
+                       return ret;
+               }
+               catch (
+                               final CoreException e
+                               )
+               {
+                       throw new IOException( e );
+               }
+       }
+
+       @Override
+       public void write(String path, InputStream out) throws IOException {
+               logger.trace( "Path :{}", path );
+               final IResource file = getFile( path );
+               final IFile f = (IFile) file.getAdapter( IFile.class );
+               
+               try {
+                       if ( f.exists() )
+                       {
+                               f.setContents( out, false, false, new NullProgressMonitor() );
+                       }
+                       else
+                       {
+                               f.create( out, false, new NullProgressMonitor() );
+                       }
+               }
+               catch ( final CoreException e )
+               {
+                       throw new IOException( e );
+               }
+       }
+
+       @Override
+       public InputStream read(
+               final String path
+       )
+       throws IOException
+       {
+               final Path p = new Path( path );
+               final IFile eFile = getWorkspace().getFileForLocation( p );
+               if ( null == eFile )
+               {
+                       return super.read( path );
+               }
+               try
+               {
+                       return eFile.getContents();
+               }
+               catch ( final CoreException e )
+               {
+                       throw new IOException( e );
+               }
+       }
+
+       @Override
+       public void moveFile(String source, String target) throws IOException {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public void copyFile(String source, String target) throws IOException {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public void removeFile(String path) throws IOException {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public Object get(String path, Attribute name) throws IOException {
+               logger.trace( "Path :{}, Attribute :{}", path, name );
+               
+               final IResource file = getFile( path );
+               if ( null == file )
+               {
+                       return super.get( path, name );
+               }
+
+               if ( Attribute.TYPE.equals( name ) )
+               {
+                       if ( file instanceof IContainer )
+                       {
+                               return Type.DIRECTORY;
+                       }
+                       else if ( file instanceof IFile )
+                       {
+                               return Type.FILE;
+                       }
+               }
+               else if ( Attribute.EXISTS.equals( name ) )
+               {
+                       return file.exists();
+
+               }
+               else if ( Attribute.PATH.equals( name ) )
+               {
+                       return file.getLocation().toPortableString();
+               }
+               else if ( Attribute.URI.equals( name ) || Attribute.URL.equals( name ) )
+               {
+                       return file.getLocationURI().toURL().toString();
+               }
+               else if ( Attribute.MODIFIED.equals( name ) )
+               {
+                       return file.getLocalTimeStamp();
+               }
+               else if ( Attribute.HIDDEN.equals( name ) )
+               {
+                       return file.isHidden();
+               }
+               else if ( Attribute.READABLE.equals( name ) )
+               {
+                       return file.isAccessible();
+               }
+               else if ( Attribute.WRITABLE.equals( name ) )
+               {
+                       return file.isAccessible();
+               }
+               throw new IOException( path + "'s Unknown attribute :" + name );
+       }
+
+       @Override
+       public void set(String path, Attribute name, Object value)
+       throws IOException {
+               if ( Attribute.QUALIFIED.equals( name ) )
+               {
+//                     signatureFile.setPersistentProperty(SignatureUtility.stateQualifiedName, "false"); //$NON-NLS-1$
+                       return ;
+               }
+
+               throw new UnsupportedOperationException();
+       }
+       
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString()
+    {
+        return getClass().getSimpleName() + "@" + Integer.toHexString( hashCode() ).substring( 0, 4 );
+    }
+       
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/FileHandler.java b/org.tizen.common/src/org/tizen/common/file/FileHandler.java
new file mode 100644 (file)
index 0000000..61d7a81
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+
+/**
+ * <p>
+ * FileHandler.
+ * 
+ * Class to handle file system as abstract api
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface
+FileHandler
+{
+       /**
+        * <p>
+        * Attribute.
+        * 
+        * File attribute
+        * </p>
+        * 
+        * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+        */
+       enum Attribute
+       {
+               CWD,            // Current Working Directory
+               PATH,           // Abstract canonical path
+               TYPE,           // Type( FILE / DIRECTORY / UNKNOWN )
+               EXISTS,         // true / false
+               READABLE,       // true / false
+               WRITABLE,       // true / false
+               HIDDEN,         // true / false
+               READONLY,       // true / false
+               MODIFIED,       // long
+               URI,                    // String
+               URL,                    // String
+               QUALIFIED,
+               CUSTOM
+       }
+
+       /**
+        * <p>
+        * Type.
+        * 
+        * Value of {@link Attribute#TYPE}
+        * </p>
+        * 
+        * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+        */
+       enum Type
+       {
+               FILE,
+               DIRECTORY,
+               UNKNOWN
+       }
+
+       /**
+        * Return cwd, abbreviating current working directory
+        * 
+        * @return current working directory
+        */
+       String getCurrentWorkingDirectory();
+
+       /**
+        * Change current working directory to <code>cwd</code>
+        * 
+        * @param cwd new current working directory
+        */
+       void setCurrentWorkingDirectory( final String cwd );
+
+       /* Directory */
+       /**
+        * Make new directory with <code>path</code>
+        * 
+        * @param path path to directory
+        * 
+        * @throws IOException If exception occured in making a directory
+        */
+       void makeDirectory( String path ) throws IOException;
+
+       /**
+        * Move <code>source</code> directory to <code>target</code>
+        * 
+        * @param source directory path to move
+        * @param target path to move to
+        * 
+        * @throws IOException If exception occured in moving a directory
+        */
+       void moveDirectory( String source, String target ) throws IOException;
+
+       /**
+        * Copy <code>source</code> directory to <code>target</code>
+        * 
+        * @param source directory path to copy
+        * @param target path to copy to
+        * 
+        * @throws IOException If exception occured in copying a directory
+        */
+       void copyDirectory( String source, String target ) throws IOException;
+
+       /**
+        * Delete <code>path</code> directory
+        * 
+        * @param path directory path to delete
+        *  
+        * @throws IOException If exception occured in deleting a directory
+        */
+       void removeDirectory( String path ) throws IOException;
+
+       /**
+        * List child directory and file in <code>path</code>
+        * 
+        * @param path directory path
+        * @return child directory and file's path
+        * 
+        * @throws IOException If exception occured in list child in directory
+        */
+       Collection<String> list( String path ) throws IOException;
+
+       /* File */
+       /**
+        * Save file in <code>path</code> using <code>out</code>
+        * 
+        * @param path file path to write
+        * @param out {@link InputStream} to provide contents
+        * 
+        * @throws IOException If exception occured in saving
+        */
+       void write( String path, InputStream out ) throws IOException;
+
+       /**
+        * Return {@link InputStream} to provice file contents
+        * 
+        * @param path file path to read
+        * @return
+        * @throws IOException
+        */
+       InputStream read( String path ) throws IOException;
+
+       /**
+        * Move <code>source</code> file to <code>target</code>
+        * 
+        * @param source file path to move
+        * @param target path to move to
+        * 
+        * @throws IOException If exception occured in moving a file
+        */
+       void moveFile( String source, String target ) throws IOException;
+
+       /**
+        * Copy <code>source</code> file to <code>target</code>
+        * 
+        * @param source file path to copy
+        * @param target path to copy to
+        * 
+        * @throws IOException If exception occured in copying a file
+        */
+       void copyFile( String source, String target ) throws IOException;
+
+       /**
+        * Delete file in <code>path</code>
+        * 
+        * @param path file path
+        * 
+        * @throws IOException If exception occured in deletion
+        */
+       void removeFile( String path ) throws IOException;
+
+       /**
+        * Return <code>path</code>'s attribute value having <code>name</code> as attribute name
+        * 
+        * @param path file path
+        * @param name attribute name
+        * 
+        * @return attribute value
+        * 
+        * @throws IOException If exception occured in reading attribute
+        */
+       Object get( final String path, Attribute name ) throws IOException;
+
+       /**
+        * Check if <code>path</code> file's attribute <code>name</code> is <code>true</code>
+        * 
+        * @param path file path to check
+        * @param name attribute name
+        * 
+        * @return boolean value if thread is <code>name</code> attribute
+        * 
+        * @throws IOException If exception occured in reading attribute
+        */
+       boolean is( final String path, Attribute name ) throws IOException;
+
+       /**
+        * Set <code>path</code> file's attribute <code>name</code> as <code>value</code>
+        * 
+        * @param path file path
+        * @param name attribute anme
+        * @param value attribute value
+        * 
+        * @throws IOException If exception occured in change file attribute
+        * 
+        * @see {@link Attribute}
+        */
+       void set( final String path, Attribute name, Object value ) throws IOException;
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/Filter.java b/org.tizen.common/src/org/tizen/common/file/Filter.java
new file mode 100644 (file)
index 0000000..17af932
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+/**
+ * <p>
+ * Filter.
+ * 
+ * Object to check if path is valid
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface Filter
+{
+       /**
+        * Check and return if <code>path</code> is valid when current working directory is <code>cwd</code>
+        * 
+        * @param cwd current working directory
+        * @param path file path
+        * 
+        * @return boolean value of validation
+        */
+       boolean accept( final String cwd, final String path );
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/PatternFilter.java b/org.tizen.common/src/org/tizen/common/file/PatternFilter.java
new file mode 100644 (file)
index 0000000..f060087
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+/**
+ * <p>
+ * PatternFilter.
+ * 
+ * {@link Filter} using pattern
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+PatternFilter
+{
+       /**
+        * Pattern string
+        */
+       protected String pattern = "*";
+
+       /**
+        * Return pattern
+        * 
+        * @return pattern
+        * 
+        * {@link #pattern}
+        */
+       public
+       String
+       getPattern()
+       {
+               return this.pattern;
+       }
+
+       /**
+        * Set pattern
+        * 
+        * @param pattern pattern to set
+        */
+       public
+       void
+       setPattern(
+               final String pattern
+       )
+       {
+               if ( null == pattern )
+               {
+                       throw new NullPointerException();
+               }
+               this.pattern = pattern;
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/SimpleFileFilter.java b/org.tizen.common/src/org/tizen/common/file/SimpleFileFilter.java
new file mode 100644 (file)
index 0000000..efd37f5
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.util.CollectionUtil;
+
+/**
+ * <p>
+ * SimpleFileFilter.
+ * 
+ * File filter using including filter and excluding filter
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+SimpleFileFilter
+implements Filter
+{
+       /**
+        * Logger for this instance
+        */
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+
+       /**
+        * Including filters
+        */
+       protected List<Filter> includes = new ArrayList<Filter>();
+
+       /**
+        * Excluding filters
+        */
+       protected List<Filter> excludes = new ArrayList<Filter>();
+
+       // Hiding collection
+       /**
+        * Clear including filters
+        */
+       public
+       void
+       clearIncludes()
+       {
+               includes.clear();
+       }
+
+       /**
+        * Set <code>filters</code> including filters
+        * 
+        * @param filters {@link Filter}s to set
+        */
+       public
+       void
+       setIncludes(
+               final Filter... filters
+       )
+       {
+               clearIncludes();
+               addIncludes( filters );
+       }
+
+       /**
+        * Add <code>filters</code> to including filters
+        * 
+        * @param filters {@link Filter}s to add
+        */
+       public
+       void
+       addIncludes(
+               final Filter... filters
+       )
+       {
+               for( final Filter filter : filters )
+               {
+                       includes.add( filter );
+               }
+               logger.debug( "Include filters[{}] added", CollectionUtil.toString( filters ) );
+       }
+
+       /**
+        * Clear excluding filters
+        */
+       public
+       void
+       clearExcludes()
+       {
+               excludes.clear();
+       }
+
+       /**
+        * Set {@link Filter}s as excluding filters
+        * @param filters
+        */
+       public
+       void
+       setExcludes(
+               final Filter... filters
+       )
+       {
+               clearExcludes();
+               addExcludes( filters );
+       }
+
+       /**
+        * Add <code>filters</code> to excluding filters
+        * 
+        * @param filters {@link Filter}s to add
+        */
+       public
+       void
+       addExcludes(
+               final Filter... filters
+       )
+       {
+               for( final Filter filter : filters )
+               {
+                       excludes.add( filter );
+               }
+               logger.debug( "Excludes filters[{}] added", CollectionUtil.toString( filters ) );
+       }
+
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.Filter#accept(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       boolean
+       accept(
+               final String cwd,
+               final String path
+       )
+       {
+               logger.trace( "Current working directory :{}, Path :{}", cwd, path );
+               logger.trace( "Excluding filters :{}", excludes );
+               for ( final Filter filter : excludes )
+               {
+                       if ( filter.accept( cwd, path ) )
+                       {
+                               logger.debug( "Deny because of {}", filter );
+                               return false;
+                       }
+               }
+
+               logger.trace( "Including filters :{}", excludes );
+               for ( final Filter filter : includes )
+               {
+                       if ( filter.accept( cwd, path ) )
+                       {
+                               logger.debug( "Accept because of {}", filter );
+                               return true;
+                       }
+               }
+
+               if ( includes.isEmpty() )
+               {
+                       return true;
+               }
+               else if ( excludes.isEmpty() )
+               {
+                       return false;
+               }
+               throw new IllegalStateException( "Include and Exclude rule is invalid" );
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/StandardFileHandler.java b/org.tizen.common/src/org/tizen/common/file/StandardFileHandler.java
new file mode 100755 (executable)
index 0000000..a0b852e
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+import static org.tizen.common.util.FilenameUtil.getCanonicalForm;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.tizen.common.util.IOUtil;
+
+/**
+ * <p>
+ * StandardFileHandler.
+ * 
+ * {@link FileHandler} to use java.io package api like {@link File}, {@link FileInputStream} and {@link FileOutputStream}
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+StandardFileHandler
+extends AbstractFileHandler
+{
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#getCurrentWorkingDirectory()
+        */
+       @Override
+       public
+       String
+       getCurrentWorkingDirectory()
+       {
+               return new File( "." ).getAbsolutePath();
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#setCurrentWorkingDirectory(java.lang.String)
+        */
+       @Override
+       public
+       void
+       setCurrentWorkingDirectory(String cwd) {
+               throw new UnsupportedOperationException();
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#makeDirectory(java.lang.String)
+        */
+       @Override
+       public
+       void
+       makeDirectory(
+               final String path
+       )
+       throws IOException
+       {
+               new File( path ).mkdir();
+
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#moveDirectory(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       void
+       moveDirectory(
+               final String source,
+               final String target
+       )
+       throws IOException
+       {
+               final File file = new File( source );
+               if ( !file.isDirectory() )
+               {
+                       throw new IOException();
+               }
+               file.renameTo( new File( target ) );
+
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#copyDirectory(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       void
+       copyDirectory(
+               final String source,
+               final String target
+       )
+       throws IOException
+       {
+               throw new UnsupportedOperationException();
+//             final Stack<File> sourceStack = new Stack<File>();
+//             final Stack<File> targetStack = new Stack<File>();
+//             sourceStack.push( new File(source ) );
+//             targetStack.push( new File( target ) );
+//
+//             while ( !sourceStack.isEmpty() )
+//             {
+//                     final File sourceFile = sourceStack.pop();
+//                     final File targetFile = targetStack.pop();
+//
+//                     if ( sourceFile.isDirectory() )
+//                     {
+//                             targetFile.mkdir();
+//                             for ( final File sourceChild : sourceFile.listFiles() )
+//                             {
+//                                     sourceStack.push( sourceChild );
+//                                     targetStack.push( new File( targetFile, sourceChild.getName() ) );
+//                             }
+//                     }
+//                     else if ( sourceFile.isFile())
+//                     {
+//                             final FileInputStream fileIn = new FileInputStream( sourceFile );
+//                             final FileOutputStream fileOut = new FileOutputStream( targetFile );
+//
+//                             IOUtil.redirect( fileIn, fileOut );
+//                             tryClose( fileOut, fileIn );
+//                     }
+//                     else {
+//                             Logger.error(sourceFile + " is not file or directory");
+//                     }
+//             }
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#removeDirectory(java.lang.String)
+        */
+       @Override
+       public
+       void
+       removeDirectory(
+               final String path
+       )
+       throws IOException
+       {
+               if ( !Type.DIRECTORY.equals( get( path, Attribute.TYPE ) ) )
+               {
+                       throw new IOException();
+               }
+
+               for ( final String childPath : list( path ) )
+               {
+                       Object type = get( childPath, Attribute.TYPE );
+                       if ( Type.DIRECTORY.equals( type ) )
+                       {
+                               removeDirectory( childPath );
+                       }
+                       else if ( Type.FILE.equals( type ) )
+                       {
+                               removeFile( childPath );
+                       }
+               }
+
+               new File( path ).delete();
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#list(java.lang.String)
+        */
+       @Override
+       public
+       Collection<String>
+       list(
+               final String path
+       )
+       throws IOException
+       {
+               final File file = new File( path );
+               final File[] children = file.listFiles();
+               final ArrayList<String> ret = new ArrayList<String>();
+               for ( final File child : children )
+               {
+                       ret.add( getCanonicalForm( child.getAbsolutePath() ) );
+               }
+
+               return ret;
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#write(java.lang.String, java.io.InputStream)
+        */
+       @Override
+       public
+       void
+       write(
+               final String path,
+               final InputStream in
+       )
+       throws IOException
+       {
+               final FileOutputStream fileOut = new FileOutputStream( path );
+
+               try
+               {
+                       IOUtil.redirect( in, fileOut );
+               }
+               finally
+               {
+                       tryClose( fileOut );
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#read(java.lang.String)
+        */
+       @Override
+       public
+       InputStream
+       read(
+               final String path
+       )
+       throws IOException
+       {
+               return new FileInputStream( path );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#moveFile(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       void
+       moveFile(
+               final String source,
+               final String target
+       )
+       throws IOException
+       {
+               final File file = new File( source );
+               if ( !file.isFile() ) 
+               {
+                       throw new IOException();
+               }
+               file.renameTo( new File( target ) );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#copyFile(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       void
+       copyFile(
+               final String source,
+               final String target
+       )
+       throws IOException
+       {
+               final File file = new File( source );
+               if ( !file.isFile() ) 
+               {
+                       throw new IOException();
+               }
+               
+               final FileInputStream sourceIn = new FileInputStream( source );
+               final FileOutputStream targetOut = new FileOutputStream( target );
+               try
+               {
+                       IOUtil.redirect( sourceIn, targetOut );
+               }
+               finally
+               {
+                       tryClose( targetOut, sourceIn );
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#removeFile(java.lang.String)
+        */
+       @Override
+       public
+       void
+       removeFile(
+               final String path
+       )
+       throws IOException
+       {
+               final File file = new File( path );
+               if ( !file.isFile() ) 
+               {
+                       throw new IOException();
+               }
+
+               file.delete();
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#get(java.lang.String, org.tizen.common.file.FileHandler.Attribute)
+        */
+       @Override
+       public
+       Object
+       get(
+               final String path,
+               final Attribute name
+       )
+       throws IOException
+       {
+               logger.trace( "Path :{}, Attribute :{}", path, name );
+               
+               final File file = new File( path );
+
+               if ( Attribute.TYPE.equals( name ) )
+               {
+                       if ( file.isDirectory() )
+                       {
+                               return Type.DIRECTORY;
+                       }
+                       else if ( file.isFile() )
+                       {
+                               return Type.FILE;
+                       }
+               }
+               else if ( Attribute.EXISTS.equals( name ) )
+               {
+                       return file.exists();
+
+               }
+               else if ( Attribute.PATH.equals( name ) )
+               {
+                       return file.getCanonicalPath();
+               }
+               else if ( Attribute.URI.equals( name ) || Attribute.URL.equals( name ) )
+               {
+                       return file.toURI().toURL().toString();
+               }
+               else if ( Attribute.MODIFIED.equals( name ) )
+               {
+                       return file.lastModified();
+               }
+               else if ( Attribute.HIDDEN.equals( name ) )
+               {
+                       return file.isHidden();
+               }
+               else if ( Attribute.READABLE.equals( name ) )
+               {
+                       return file.canRead();
+               }
+               else if ( Attribute.WRITABLE.equals( name ) )
+               {
+                       return file.canWrite();
+               }
+               throw new IOException( path + "'s Unknown attribute :" + name );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#set(java.lang.String, org.tizen.common.file.FileHandler.Attribute, java.lang.Object)
+        */
+       @Override
+       public void
+       set(
+               final String path,
+               final Attribute name,
+               final Object value
+       )
+       throws IOException
+       {
+       }
+
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/VirtualFileHandler.java b/org.tizen.common/src/org/tizen/common/file/VirtualFileHandler.java
new file mode 100644 (file)
index 0000000..c35f4d0
--- /dev/null
@@ -0,0 +1,798 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+import static org.tizen.common.util.ArrayUtil.size;
+import static org.tizen.common.util.FilenameUtil.SEPARATOR_DIRECTORY;
+import static org.tizen.common.util.FilenameUtil.addTailingPath;
+import static org.tizen.common.util.FilenameUtil.getCanonicalFragments;
+import static org.tizen.common.util.FilenameUtil.getFilename;
+import static org.tizen.common.util.FilenameUtil.removeTailingPath;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.util.IOUtil;
+import org.tizen.common.util.StringUtil;
+
+/**
+ * <p>
+ * VirtualFileHandler.
+ * 
+ * {@link FileHandler} to handling in memory
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+VirtualFileHandler
+extends AbstractFileHandler
+{
+
+       /**
+        * <p>
+        * File.
+        * 
+        * File contents container
+        *
+        * </p>
+        * 
+        * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+        */
+       private class
+       File
+       implements Cloneable
+       {
+               /**
+                * File name
+                */
+               String name;
+               
+               /**
+                * File contents
+                */
+               byte[] contents;
+               
+               /**
+                * File attributes
+                */
+               HashMap<Attribute, Object> attr = new HashMap<Attribute, Object>();
+
+               /**
+                * Default constructor
+                */
+               public File()
+               {
+               }
+
+               /**
+                * Constructor with name and contents
+                * 
+                * @param name file name
+                * @param contents file contents
+                */
+               public
+               File(
+                       final String name,
+                       final byte[] contents
+               )
+               {
+                       this.name = name;
+                       this.contents = contents;
+               }
+
+               /**
+                * Return file name
+                * 
+                * @return file name
+                */
+               public
+               String
+               getName()
+               {
+                       return this.name;
+               }
+
+               /**
+                * Return file contents
+                * 
+                * @return file contents
+                */
+               public
+               byte[] getContents()
+               {
+                       return this.contents;
+               }
+
+               /**
+                * Set <code>contents</code> as file contents
+                * 
+                * @param contents new file contents
+                */
+               public
+               void
+               setContents(
+                       final byte[] contents
+               )
+               {
+                       this.contents = contents;
+               }
+
+               /**
+                * Set file attribute value whose name is <code>name</code> as <code>value</code>
+                * 
+                * @param name attribute name
+                * @param value attribute value
+                */
+               public
+               void
+               setAttribute(
+                       final Attribute name,
+                       final Object value
+               )
+               {
+                       attr.put( name, value );
+               }
+               /**
+                * Return file attribute value whose name is <code>name</code>
+                * 
+                * @param name attribute name
+                * 
+                * @return attribute value
+                */
+               public
+               Object
+               getAttribute(
+                       final Attribute name
+               )
+               {
+                       return attr.get( name );
+               }
+
+               /* (non-Javadoc)
+                * @see java.lang.Object#clone()
+                */
+               @Override
+               public
+               Object
+               clone()
+               {
+                       final File file = new File();
+                       file.name = this.name;
+                       file.contents = this.contents;
+                       return file;
+               }
+
+       }
+
+       /**
+        * <p>
+        * Directory.
+        * 
+        * Directory in memory
+        *
+        * </p>
+        * 
+        * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+        */
+       class Directory
+       extends File
+       implements Cloneable
+       {
+               /**
+                * Child files & directories
+                */
+               protected final HashMap<String, File> name2file = new HashMap<String, File>();
+
+               /**
+                * Default constructor
+                */
+               public Directory()
+               {
+               }
+
+               /**
+                * Constructor with directory name
+                * 
+                * @param name directory name
+                */
+               public
+               Directory(
+                       final String name
+               )
+               {
+                       super( name, null );
+               }
+
+               /**
+                * Return child file whose name is <code>name</code>
+                * 
+                * @param name file name
+                * 
+                * @return {@link File}
+                */
+               public
+               File
+               get(
+                       final String name
+               )
+               {
+                       return name2file.get( name );
+               }
+
+               /**
+                * Delete child file whose name is <code>name</code>
+                * 
+                * @param name file name
+                * 
+                * @return file to be deleted
+                */
+               public
+               File
+               remove(
+                       final String name
+               )
+               {
+                       return name2file.remove( name );
+               }
+
+               /**
+                * Add new file whose name is <code>contents<code> and whose contents is <code>contents</code>
+                * 
+                * @param name file name
+                * @param contents file contents
+                */
+               public
+               void
+               add(
+                       final String name,
+                       final byte[] contents
+               )
+               {
+                       name2file.put( name, new File( name, contents ) );
+               }
+
+               /**
+                * Add directory whose name is <code>name</code>
+                * 
+                * @param name directory name
+                */
+               public
+               void
+               add(
+                       final String name
+               )
+               {
+                       name2file.put( name, new Directory( name ) );
+               }
+
+               /**
+                * Add <code>file</code>
+                * 
+                * @param file file or directory to add
+                */
+               public
+               void
+               add(
+                       final File file
+               )
+               {
+                       name2file.put( file.getName(), file );
+               }
+
+               /* (non-Javadoc)
+                * @see org.tizen.common.file.VirtualFileHandler.File#clone()
+                */
+               @Override
+               public
+               Object
+               clone()
+               {
+                       final Directory dir = new Directory();
+                       dir.contents = this.contents;
+                       dir.name = this.name;
+                       for ( final String name : name2file.keySet() )
+                       {
+                               name2file.put( name, (File) name2file.get( name ).clone() );
+                       }
+
+                       return dir;
+               }
+
+               /* (non-Javadoc)
+                * @see java.lang.Object#toString()
+                */
+               @Override
+               public
+               String
+               toString()
+               {
+                       return name2file.keySet().toString();
+               }
+       }
+
+       /**
+        * Prefix abstract path
+        */
+       protected static final String ROOT_PREFIX = "/";
+
+       /**
+        * Logger for this instance
+        */
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+
+       /**
+        * Root directory
+        */
+       protected final Directory root = new Directory();
+
+       /**
+        * Current working directory
+        */
+       protected String cwd = "/";
+
+       /**
+        * Return {@link File} matching with <code>path</code>
+        * 
+        * @param path file path
+        * @return {@link File} matching with <code>path</code>
+        * 
+        * @throws IOException If file is not accessible
+        */
+       protected
+       File
+       getFile(
+               final String path
+       )
+       throws IOException
+       {
+               logger.trace( "Path :{}", path );
+
+               final String[] fragments = getCanonicalFragments( path );
+
+               File iter = root;
+               for ( int i = 0, n = fragments.length ; i < n ; ++i )
+               {
+                       Directory dir = (Directory) iter;
+                       iter = dir.get( fragments[i] );
+                       if ( null == iter )
+                       {
+                               logger.debug( "fragment :{}", fragments[i] );
+                               logger.debug( "in-processing directory :{}", dir );
+
+                               throw new IOException( "Can't access " + path );
+                       }
+               }
+
+               return iter;
+       }
+
+       /**
+        * Return parent directory of file matching with <code>path</code>
+        * @param path file path
+        * 
+        * @return parent directory
+        * 
+        * @throws IOException If file or directory is not accessible
+        */
+       public
+       Directory
+       getParent(
+               final String path
+       )
+       throws IOException
+       {
+               final File parent = getFile( removeTailingPath( path, 1 ) );
+               if ( !( parent instanceof Directory ) )
+               {
+                       throw new IOException();
+               }
+
+               return (Directory) parent;
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#makeDirectory(java.lang.String)
+        */
+       @Override
+       public
+       void
+       makeDirectory(
+               final String path
+       )
+       throws IOException
+       {
+               final Directory parent = getParent( path );
+               final String dirName = getFilename( path );
+               parent.add( dirName );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#moveDirectory(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       void
+       moveDirectory(
+               final String source,
+               final String target
+       )
+       throws IOException
+       {
+               final String filename = getFilename( source );
+
+               final Directory parent = getParent( source );
+               final File file = parent.get( filename );
+               if ( !( file instanceof Directory ) )
+               {
+                       throw new IOException();
+               }
+               final Directory newParent = (Directory) getFile( target );
+               newParent.add( newParent.remove( filename ) );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#copyDirectory(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       void
+       copyDirectory(
+               final String source,
+               final String target
+       )
+       throws IOException
+       {
+               final Directory dir = (Directory) getFile( source );
+               final Directory targetDir = (Directory) getFile( target );
+
+               targetDir.add( (File) dir.clone() );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#removeDirectory(java.lang.String)
+        */
+       @Override
+       public
+       void
+       removeDirectory(
+               final String path
+       )
+       throws IOException
+       {
+               final Directory dir = getParent( path );
+               final String name = getFilename( path );
+               dir.remove( name );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#list(java.lang.String)
+        */
+       @Override
+       public
+       Collection<String>
+       list(
+               final String path
+       )
+       throws IOException
+       {
+               final Directory dir = (Directory) getFile( path );
+               final Collection<String> childNames = dir.name2file.keySet();
+               logger.trace( "Directory[{}]'s child :{}", path, childNames );
+
+               final ArrayList<String> fullNames = new ArrayList<String>();
+
+               for ( final String name : dir.name2file.keySet() )
+               {
+                       fullNames.add( addTailingPath( path, name )  );
+               }
+
+               logger.debug( "Fullnames :\n{}", fullNames );
+               return fullNames;
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#write(java.lang.String, java.io.InputStream)
+        */
+       @Override
+       public
+       void
+       write(
+               final String path,
+               final InputStream in
+       )
+       throws IOException
+       {
+               final Directory parent = getParent( path );
+               if ( !(parent instanceof Directory ) )
+               {
+                       throw new IOException();
+               }
+
+               final String filename = getFilename( path );
+
+               File file = parent.get( filename );
+
+               if ( file instanceof Directory )
+               {
+                       throw new IOException();
+               }
+               if ( null == file )
+               {
+                       file = new File( getFilename( path ), null );
+               }
+               getParent( path ).add( file );
+
+               final byte[] contents = IOUtil.getBytes( in );
+
+               if ( logger.isTraceEnabled() )
+               {
+                       int nSize = size( contents );
+                       logger.trace(
+                               "Save file[{}] :{} byte(s)\n{}",
+                               new Object[] {
+                                       path,
+                                       nSize,
+                                       StringUtil.text2hexa( contents, 0, Math.min( 64, size( contents ) ) ) + ( (64 < size( contents ) )?"...":"" )
+                               }
+                       );
+               }
+
+               file.setContents( contents );
+       }
+
+       /**
+        * write <code>contents</code> to file with <code>path</code>
+        * 
+        * @param path file path
+        * @param contents file contents
+        * 
+        * @throws IOException If file can't be writable
+        * 
+        * @see {@link #write(String, InputStream)}
+        */
+       public
+       void
+       write(
+               final String path,
+               final String contents
+       )
+       throws IOException
+       {
+               logger.trace( "Save file :{}\n{}", path, contents );
+               final InputStream in = new ByteArrayInputStream( (null==contents)?(new byte[0]):contents.getBytes() );
+               try
+               {
+                       write( path, in );
+               }
+               finally
+               {
+                       tryClose( in );
+               }
+
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#read(java.lang.String)
+        */
+       @Override
+       public
+       InputStream
+       read(
+               final String path
+       )
+       throws IOException
+       {
+               final File file = getFile( path );
+               if ( file instanceof Directory )
+               {
+                       throw new IOException();
+               }
+
+               return new ByteArrayInputStream( file.contents );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#moveFile(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       void
+       moveFile(
+               final String source,
+               final String target
+       )
+       throws IOException
+       {
+               final Directory directory = getParent( source );
+               final String fileName = getFilename( source );
+               final File file = directory.remove( fileName );
+               if ( null == file )
+               {
+                       throw new IOException();
+               }
+               
+               final Directory targetDirectory = (Directory) getFile( target );
+               targetDirectory.add( file );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#copyFile(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       void
+       copyFile(
+               final String source,
+               final String target
+       )
+       throws IOException
+       {
+               final Directory directory = getParent( source );
+               final String fileName = getFilename( source );
+               final File file = directory.get( fileName );
+               if ( null == file )
+               {
+                       throw new IOException();
+               }
+               
+               final Directory targetDirectory = (Directory) getFile( target );
+               targetDirectory.add( (File) file.clone() );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#removeFile(java.lang.String)
+        */
+       @Override
+       public
+       void
+       removeFile(
+               final String path
+       )
+       throws IOException
+       {
+               final File file = getFile( path );
+               if ( file instanceof Directory )
+               {
+                       throw new IOException();
+               }
+               
+               final Directory directory = getParent( path );
+               final String fileName = getFilename( path );
+               directory.remove( fileName );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#get(java.lang.String, org.tizen.common.file.FileHandler.Attribute)
+        */
+       @Override
+       public
+       Object
+       get(
+               final String path,
+               final Attribute name
+       )
+       throws IOException
+       {
+               File file = null;
+               try {
+                       file = getFile( path );
+               } catch ( Throwable e )
+               {
+               }
+               if ( Attribute.TYPE.equals( name ) )
+               {
+                       if ( file instanceof Directory )
+                       {
+                               return Type.DIRECTORY;
+                       }
+                       else if ( file instanceof File )
+                       {
+                               return Type.FILE;
+                       }
+               }
+               else if ( Attribute.EXISTS.equals( name ) )
+               {
+                       return ( null != file );
+
+               }
+               else if ( Attribute.PATH.equals( name ) )
+               {
+                       if ( path.startsWith( ROOT_PREFIX ) )
+                       {
+                               return path;
+                       }
+
+                       return cwd + SEPARATOR_DIRECTORY + path;
+               }
+               else if ( Attribute.URI.equals( name ) || Attribute.URL.equals( name ) )
+               {
+                       return "vf://" + path;
+               }
+               else
+               {
+                       file.getAttribute( name );
+                       return false;
+               }
+               throw new IOException( path + "'s Unknown attribute :" + name );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#set(java.lang.String, org.tizen.common.file.FileHandler.Attribute, java.lang.Object)
+        */
+       @Override
+       public
+       void
+       set(
+               final String path,
+               final Attribute name,
+               final Object value
+       )
+       throws IOException
+       {
+               File file = null;
+               try {
+                       file = getFile( path );
+               } catch ( Throwable e )
+               {
+               }
+               if ( null != file )
+               {
+                       file.setAttribute( name, value );
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#getCurrentWorkingDirectory()
+        */
+       @Override
+       public
+       String
+       getCurrentWorkingDirectory() {
+               return this.cwd;
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.FileHandler#setCurrentWorkingDirectory(java.lang.String)
+        */
+       @Override
+       public
+       void
+       setCurrentWorkingDirectory(
+               final String cwd
+       )
+       {
+               this.cwd = cwd;
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/filter/WildCardFilter.java b/org.tizen.common/src/org/tizen/common/file/filter/WildCardFilter.java
new file mode 100644 (file)
index 0000000..04ccb0e
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Common
+ *
+ * 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.common.file.filter;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.file.Filter;
+import org.tizen.common.file.PatternFilter;
+import org.tizen.common.util.FilenameUtil;
+
+/**
+ * WildCardFilter
+ * 
+ * Filter using wildcard( ?, * )
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+WildCardFilter
+extends PatternFilter
+implements Filter
+{
+       /**
+        * Logger for this instance
+        */
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+       
+       /**
+        * Default constructor
+        */
+       public WildCardFilter()
+       {
+       }
+       
+       /**
+        * Constructor with pattern
+        * 
+        * @param pattern pattern to apply
+        */
+       public WildCardFilter( final String pattern )
+       {
+               setPattern( pattern );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.file.Filter#accept(java.lang.String, java.lang.String)
+        */
+       @Override
+       public
+       boolean
+       accept(
+               final String cwd,
+               final String path
+       )
+       {
+               logger.trace( "Current working directory :{}, Path :{}", cwd, path );
+               final String name = FilenameUtil.getFilename( path );
+               logger.trace( "Name :{}", name );
+               return FilenameUtils.wildcardMatch( name, getPattern() );
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public
+       String
+       toString()
+       {
+               return WildcardFileFilter.class.getName() + "[" + getPattern() + "]";
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/file/filter/WildCardFilterFactory.java b/org.tizen.common/src/org/tizen/common/file/filter/WildCardFilterFactory.java
new file mode 100644 (file)
index 0000000..2cafcbf
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Common
+ *
+ * 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.common.file.filter;
+
+import org.tizen.common.FactoryWithArgument;
+import org.tizen.common.file.Filter;
+
+/**
+ * <p>
+ * WildCardFilterFactory.
+ *
+ * Factory to create {@link WildCardFilter} for pattern
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+WildCardFilterFactory
+implements FactoryWithArgument<Filter, String>
+{
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.FactoryWithArgument#create(java.lang.Object)
+        */
+       @Override
+       public
+       Filter
+       create(
+               final String arg
+       )
+       {
+               final WildCardFilter filter = new WildCardFilter();
+               filter.setPattern( arg );
+               return filter;
+       }
+
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/handler/ClearHandler.java b/org.tizen.common/src/org/tizen/common/handler/ClearHandler.java
deleted file mode 100644 (file)
index ba8c727..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* 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.common.handler;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.handlers.HandlerUtil;
-import org.tizen.common.manager.StatusLineMessageManager;
-import org.tizen.common.model.ITableModel;
-
-
-
-public class ClearHandler extends AbstractHandler {
-       private IViewPart part;
-       private TableViewer viewer;
-       private StatusLineMessageManager statusLine;
-       
-       private String message = Messages.ClearHandler_0;
-       
-       public Object execute(ExecutionEvent event) throws ExecutionException {
-
-               part = (IViewPart)HandlerUtil.getActivePart(event);
-               viewer = (TableViewer)part.getSite().getSelectionProvider();
-               statusLine = new StatusLineMessageManager(part);
-               
-               clearData();
-               return null;
-       }
-
-       private void clearData() throws ExecutionException {
-               ITableModel model = (ITableModel)viewer.getInput();
-               model.clear();
-               viewer.refresh();
-               statusLine.setMessage(message);
-       }
-       
-       
-}
-
diff --git a/org.tizen.common/src/org/tizen/common/handler/ClipboardHandler.java b/org.tizen.common/src/org/tizen/common/handler/ClipboardHandler.java
deleted file mode 100644 (file)
index e31e5ee..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.handler;\r
-\r
-import org.eclipse.core.commands.AbstractHandler;\r
-import org.eclipse.core.commands.ExecutionEvent;\r
-import org.eclipse.core.commands.ExecutionException;\r
-import org.eclipse.swt.dnd.Clipboard;\r
-import org.eclipse.ui.handlers.HandlerUtil;\r
-\r
-/**\r
- * Superclass for clipboard related handlers providing safe creation and\r
- * disposal of the {@link Clipboard}.\r
- */\r
-public abstract class ClipboardHandler extends AbstractHandler {\r
-       public Object execute(ExecutionEvent event) throws ExecutionException {\r
-               Clipboard clipboard = new Clipboard(HandlerUtil.getActiveShell(event)\r
-                               .getDisplay());\r
-               try {\r
-                       return execute(event, clipboard);\r
-               } finally {\r
-                       clipboard.dispose();\r
-               }\r
-       }\r
-\r
-       protected abstract Object execute(ExecutionEvent event, Clipboard clipboard)\r
-                       throws ExecutionException;\r
-}
\ No newline at end of file
diff --git a/org.tizen.common/src/org/tizen/common/handler/CopyHandler.java b/org.tizen.common/src/org/tizen/common/handler/CopyHandler.java
deleted file mode 100644 (file)
index 54d604f..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.handler;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-\r
-import org.eclipse.core.commands.ExecutionEvent;\r
-import org.eclipse.core.commands.ExecutionException;\r
-import org.eclipse.core.resources.IResource;\r
-import org.eclipse.core.runtime.IAdaptable;\r
-import org.eclipse.jface.viewers.ISelection;\r
-import org.eclipse.jface.viewers.IStructuredSelection;\r
-import org.eclipse.swt.SWTError;\r
-import org.eclipse.swt.dnd.Clipboard;\r
-import org.eclipse.swt.dnd.TextTransfer;\r
-import org.eclipse.swt.dnd.Transfer;\r
-import org.eclipse.ui.handlers.HandlerUtil;\r
-import org.eclipse.ui.part.ResourceTransfer;\r
-\r
-/**\r
- * Copy each currently selected object in the Favorites view to the clipboard.\r
- */\r
-public class CopyHandler extends ClipboardHandler {\r
-       /**\r
-        * Called by the superclass {@link #execute(ExecutionEvent)} method so that\r
-        * this method can concentrate on the operation and does not have to manage\r
-        * clipboard creation and disposal.\r
-        */\r
-       public Object execute(ExecutionEvent event, Clipboard clipboard)\r
-                       throws ExecutionException {\r
-               ISelection selection = HandlerUtil.getCurrentSelection(event);\r
-               if (selection instanceof IStructuredSelection) {\r
-                       Object[] objects = ((IStructuredSelection) selection).toArray();\r
-                       if (objects.length > 0) {\r
-                               try {\r
-                                       clipboard.setContents(new Object[] { asResources(objects),\r
-                                                       asText(objects), }, new Transfer[] {\r
-                                                       ResourceTransfer.getInstance(),\r
-                                                       TextTransfer.getInstance(), });\r
-                               } catch (SWTError error) {\r
-                                       // Copy to clipboard failed.\r
-                                       // This happens when another application\r
-                                       // is accessing the clipboard while we copy.\r
-                                       // Ignore the error.\r
-                               }\r
-                       }\r
-               }\r
-               return null;\r
-       }\r
-\r
-       public static IResource[] asResources(Object[] objects) {\r
-               Collection<IResource> resources = new ArrayList<IResource>(\r
-                               objects.length);\r
-               for (int i = 0; i < objects.length; i++) {\r
-                       Object each = objects[i];\r
-                       if (each instanceof IAdaptable) {\r
-                               IResource res = (IResource) ((IAdaptable) each)\r
-                                               .getAdapter(IResource.class);\r
-                               if (res != null)\r
-                                       resources.add(res);\r
-                       }\r
-               }\r
-               return resources.toArray(new IResource[resources.size()]);\r
-       }\r
-\r
-       public static String asText(Object[] objects) {\r
-               StringBuffer buf = new StringBuffer();\r
-               for (int i = 0; i < objects.length; i++) {\r
-                       Object each = objects[i];\r
-                       if (each != null) {\r
-                               buf.append(each.toString());\r
-                       }\r
-                       buf.append(System.getProperty("line.separator")); //$NON-NLS-1$\r
-               }\r
-               return buf.toString();\r
-       }\r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/handler/Messages.java b/org.tizen.common/src/org/tizen/common/handler/Messages.java
deleted file mode 100644 (file)
index 7cb9e48..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* 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.common.handler;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
-       private static final String BUNDLE_NAME = "org.tizen.common.handler.messages"; //$NON-NLS-1$
-       public static String ClearHandler_0;
-       public static String OpenFileHandler_0;
-       public static String OpenFileHandler_2;
-       public static String OpenFileHandler_3;
-       public static String SaveFileHandler_0;
-       public static String SaveFileHandler_1;
-       public static String SaveFileHandler_11;
-       public static String SaveFileHandler_12;
-       public static String SaveFileHandler_4;
-       public static String SaveFileHandler_5;
-       static {
-               // initialize resource bundle
-               NLS.initializeMessages(BUNDLE_NAME, Messages.class);
-       }
-
-       private Messages() {
-       }
-}
diff --git a/org.tizen.common/src/org/tizen/common/handler/OpenFileHandler.java b/org.tizen.common/src/org/tizen/common/handler/OpenFileHandler.java
deleted file mode 100644 (file)
index f97b3e0..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* 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.common.handler;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.filesystem.EFS;
-import org.eclipse.core.filesystem.IFileInfo;
-import org.eclipse.core.filesystem.IFileStore;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.handlers.HandlerUtil;
-import org.eclipse.ui.ide.IDE;
-import org.tizen.common.manager.StatusLineMessageManager;
-
-
-
-public class OpenFileHandler extends AbstractHandler {
-       private IViewPart part;
-       private String fileName;
-       private Shell shell;
-       private IWorkbenchPage page;
-       private StatusLineMessageManager statusLine;
-       
-       private final String title = Messages.OpenFileHandler_0;
-       private final String PARAMETER_ID = "org.tizen.common.command.openFile.parameter"; //$NON-NLS-1$
-
-       public Object execute(ExecutionEvent event) throws ExecutionException {
-
-               part = (IViewPart)HandlerUtil.getActivePart(event);
-               shell = part.getSite().getShell();
-               page = part.getSite().getPage();
-               statusLine = new StatusLineMessageManager(part);
-               
-               String extension = event.getParameter(PARAMETER_ID);
-               
-               openFile(extension);
-               return null;
-       }
-
-       private void openFile(String extension) throws ExecutionException {
-               fileName = getLoadFileName(extension);
-               if(fileName==null)
-                       return;
-               
-               IFileStore fileStore = EFS.getLocalFileSystem().getStore(new Path(fileName));
-               IFileInfo fileInfo = fileStore.fetchInfo();
-               fileInfo.setAttribute(EFS.ATTRIBUTE_READ_ONLY, true);
-               
-               if( fileInfo.isDirectory()||!fileInfo.exists() ){
-                       statusLine.setErrorMessage(Messages.OpenFileHandler_2);
-                       return;
-               }
-               
-       try {
-                       IDE.openEditorOnFileStore(page, fileStore);
-               } catch (PartInitException e) {
-                       statusLine.setErrorMessage(fileName+ Messages.OpenFileHandler_3);
-                       return;
-               }
-
-       }
-       
-       private String getLoadFileName(String extension) {
-               String[] extFilter = {"*."+extension}; //$NON-NLS-1$
-               
-               FileDialog dialog = new FileDialog(shell, SWT.OPEN);
-               dialog.setFilterExtensions(extFilter);
-               dialog.setText(title);
-               return dialog.open();
-       }
-       
-}
-
diff --git a/org.tizen.common/src/org/tizen/common/handler/OpenPreferencesHandler.java b/org.tizen.common/src/org/tizen/common/handler/OpenPreferencesHandler.java
deleted file mode 100644 (file)
index 32932b8..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* 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.common.handler;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.preference.PreferenceDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.dialogs.PreferencesUtil;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-public class OpenPreferencesHandler extends AbstractHandler {
-       private IViewPart part;
-       private Shell shell;
-       private final String PARAMETER_ID = "org.tizen.common.command.setting.parameter"; //$NON-NLS-1$
-       
-       public Object execute(ExecutionEvent event) throws ExecutionException {
-
-               part = (IViewPart)HandlerUtil.getActivePart(event);
-               shell = part.getSite().getShell();
-               
-               String preferenceId = event.getParameter(PARAMETER_ID);
-               openPreferences(preferenceId);
-               return null;
-       }
-
-       private void openPreferences(String preferenceId) throws ExecutionException {
-               PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(shell,
-                               preferenceId, null, null);
-               dialog.open();
-       }
-       
-       
-       
-}
-
diff --git a/org.tizen.common/src/org/tizen/common/handler/SaveFileHandler.java b/org.tizen.common/src/org/tizen/common/handler/SaveFileHandler.java
deleted file mode 100644 (file)
index c703e30..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* 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.common.handler;
-
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.handlers.HandlerUtil;
-import org.tizen.common.manager.StatusLineMessageManager;
-import org.tizen.common.model.ITableModel;
-import org.tizen.common.util.DialogUtil;
-
-
-
-public class SaveFileHandler extends AbstractHandler {
-       private IViewPart part;
-       private TableViewer viewer;
-       private String fileName;
-       private Shell shell;
-       private StatusLineMessageManager statusLine;
-       
-       private final String title = Messages.SaveFileHandler_0;
-       private final String PARAMETER_ID = "org.tizen.common.command.saveFile.parameter"; //$NON-NLS-1$
-
-
-       public Object execute(ExecutionEvent event) throws ExecutionException {
-
-               part = (IViewPart)HandlerUtil.getActivePart(event);
-               shell = part.getSite().getShell();
-               statusLine = new StatusLineMessageManager(part);
-               
-               viewer = (TableViewer)part.getSite().getSelectionProvider();
-               String extension = event.getParameter(PARAMETER_ID);
-               
-               if(!hasRecord())
-                       return null;
-               
-               try {
-                       saveFile(extension);
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-
-               return null;
-       }
-
-       private void saveFile(String extension) throws InvocationTargetException, InterruptedException {
-               fileName = getSaveFileName(extension);
-               
-               if(fileName==null)
-                       return;
-               
-               if(!fileName.endsWith("."+extension)) //$NON-NLS-1$
-                       fileName= fileName+"."+extension; //$NON-NLS-1$
-               
-               if(!(new File(fileName).getParentFile().canWrite())){
-                       DialogUtil.openErrorDialog(Messages.SaveFileHandler_4);
-                       return;
-               }
-                       
-               part.getSite().getWorkbenchWindow().run(false, false, new IRunnableWithProgress(){
-                       public void run(IProgressMonitor monitor) {
-                               monitor.beginTask(Messages.SaveFileHandler_5, 100);
-                               writeRecord();
-                               monitor.done();
-                       }
-               });
-               
-               showRecordCount();
-                       
-       }
-
-       private String getSaveFileName(String extension) {
-               String[] extFilter = {"*."+extension,"*.*"}; //$NON-NLS-1$ //$NON-NLS-2$
-               
-               FileDialog dialog = new FileDialog(shell, SWT.SAVE);
-               dialog.setFilterExtensions(extFilter);
-               dialog.setText(title);
-               dialog.setOverwrite(true);
-               dialog.setFileName("untitled."+extension); //$NON-NLS-1$
-               dialog.setFilterPath(System.getProperty("user.home")); //$NON-NLS-1$
-               
-               return dialog.open();
-       }
-       
-       private void writeRecord() {
-               ITableModel model = (ITableModel) viewer.getInput();
-               model.save(fileName);
-       }
-       
-       private void showRecordCount() {
-               int size = ((ITableModel) viewer.getInput()).size();
-               statusLine.setMessage(Messages.SaveFileHandler_1+size+Messages.SaveFileHandler_11 + fileName);
-       }
-       
-       private boolean hasRecord() {
-               int size = ((ITableModel) viewer.getInput()).size();
-               if(size==0){
-                       statusLine.setErrorMessage(Messages.SaveFileHandler_12);
-                       return false;
-               }else
-                       statusLine.setErrorMessage(""); //$NON-NLS-1$
-                       return true;
-       }
-}
-
diff --git a/org.tizen.common/src/org/tizen/common/handler/messages.properties b/org.tizen.common/src/org/tizen/common/handler/messages.properties
deleted file mode 100644 (file)
index f9d98c9..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-ClearHandler_0=All data is cleared
-OpenFileHandler_0=Load File
-OpenFileHandler_2=Input file doesn't exist or isn't a file
-OpenFileHandler_3=isn't opened for internal error
-SaveFileHandler_0=Save File
-SaveFileHandler_1=Total 
-SaveFileHandler_11=\ record is saved into 
-SaveFileHandler_12=There is no record.
-SaveFileHandler_4=You can store a file into the directory that has write permission. please select another directory
-SaveFileHandler_5=Save File
diff --git a/org.tizen.common/src/org/tizen/common/manager/StatusLineMessageManager.java b/org.tizen.common/src/org/tizen/common/manager/StatusLineMessageManager.java
deleted file mode 100644 (file)
index 77d279e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* 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.common.manager;
-
-import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.IWorkbenchPart;
-
-public class StatusLineMessageManager{
-       private IViewPart part;
-       private IStatusLineManager manager;
-       
-       public StatusLineMessageManager(IWorkbenchPart part){
-               this.part = (IViewPart)part;
-               this.manager = this.part.getViewSite().getActionBars().getStatusLineManager();
-       }
-       
-       public void setErrorMessage(String message){
-               manager.setErrorMessage(message);
-       }
-       
-       public void setMessage(String message){
-               manager.setMessage(message);
-       }
-}
\ No newline at end of file
diff --git a/org.tizen.common/src/org/tizen/common/manager/messages.properties b/org.tizen.common/src/org/tizen/common/manager/messages.properties
deleted file mode 100644 (file)
index 19dbd56..0000000
+++ /dev/null
@@ -1 +0,0 @@
-ColorCache_0=Argument must not be null
diff --git a/org.tizen.common/src/org/tizen/common/model/AbstractTableModel.java b/org.tizen.common/src/org/tizen/common/model/AbstractTableModel.java
deleted file mode 100644 (file)
index 97555e6..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-import java.io.File;\r
-import java.io.FileNotFoundException;\r
-import java.io.FileReader;\r
-import java.io.FileWriter;\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Iterator;\r
-\r
-import org.eclipse.ui.IMemento;\r
-import org.eclipse.ui.XMLMemento;\r
-\r
-public abstract class AbstractTableModel implements ITableModel {\r
-       private static final String TAG_ROOT = "root"; //$NON-NLS-1$\r
-\r
-       private Collection<AbstractTableVO> inventory = new ArrayList<AbstractTableVO>();\r
-       protected AbstractTableVO source;\r
-       private boolean isDirty = false;\r
-\r
-       public AbstractTableModel(AbstractTableVO source) {\r
-               this.source = source;\r
-               \r
-       }\r
-       \r
-       \r
-\r
-       public ITableVO[] getDatas() {\r
-               if (inventory == null)\r
-                       return null;\r
-\r
-               return inventory.toArray(new AbstractTableVO[inventory.size()]);\r
-       }\r
-\r
-       public void add(Collection<AbstractTableVO> datas) {\r
-               if (datas == null)\r
-                       return;\r
-\r
-               inventory.addAll(datas);\r
-       }\r
-       \r
-       public int size(){\r
-               return inventory.size();\r
-       }\r
-\r
-       public void add(AbstractTableVO data) {\r
-               inventory.add(data);\r
-       }\r
-\r
-       public void remove(Collection<AbstractTableVO> datas) {\r
-               if (datas == null)\r
-                       return;\r
-\r
-               inventory.removeAll(datas);\r
-       }\r
-\r
-       public void remove(AbstractTableVO data) {\r
-               inventory.remove(data);\r
-       }\r
-       \r
-       public void clear() {\r
-               inventory.clear();\r
-       }\r
-\r
-       public void load(String fileName) {\r
-               if (inventory==null||source==null)\r
-                return;\r
-               \r
-               FileReader reader = null;\r
-               try {\r
-                       reader = new FileReader(new File(fileName));\r
-                       load(XMLMemento.createReadRoot(reader));\r
-               } catch (FileNotFoundException e) {\r
-                       e.printStackTrace();\r
-               } catch (Exception e) {\r
-                       e.printStackTrace();\r
-               } finally {\r
-                       try {\r
-                               if (reader != null)\r
-                                       reader.close();\r
-                       } catch (IOException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-               }\r
-       }\r
-\r
-       private void load(XMLMemento memento) {\r
-               IMemento[] children = memento.getChildren(getSourceName());\r
-               AbstractTableVO data = null;\r
-               String[] fields = source.getColumnNames();\r
-               for (int i = 0; i < children.length; i++) {\r
-                       data = source.clone();\r
-                       for (int j = 0; j < fields.length; j++) {\r
-                               data.setColumnValue(j, children[i].getString(fields[j]));\r
-                       }\r
-                       add(data);\r
-               }\r
-       }\r
-\r
-       public void save(String fileName) {\r
-               if (inventory == null || source == null)\r
-                       return;\r
-\r
-               XMLMemento memento = XMLMemento.createWriteRoot(TAG_ROOT);\r
-               save(memento);\r
-               FileWriter writer = null;\r
-               try {\r
-                       writer = new FileWriter(fileName);\r
-                       memento.save(writer);\r
-               } catch (IOException e) {\r
-                       e.printStackTrace();\r
-               } finally {\r
-                       try {\r
-                               if (writer != null)\r
-                                       writer.close();\r
-                       } catch (IOException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-               }\r
-       }\r
-\r
-       private void save(XMLMemento memento) {\r
-               Iterator<AbstractTableVO> iter = inventory.iterator();\r
-               AbstractTableVO data = null;\r
-               String[] fields = null;\r
-\r
-               while (iter.hasNext()) {\r
-                       data = iter.next();\r
-                       fields = data.getColumnNames();\r
-                       IMemento child = memento.createChild(getSourceName());\r
-                       for (int j = 0; j < fields.length; j++) {\r
-                               child.putString(\r
-                                               fields[j], \r
-                                               String.valueOf(data.getColumnValue(j)));\r
-                       }\r
-               }\r
-\r
-       }\r
-\r
-       public String getSourceName() {\r
-               return this.source.getClass().getSimpleName();\r
-       }\r
-       \r
-       public boolean isDirty(){\r
-               return this.isDirty;\r
-       }\r
-       \r
-       public synchronized void setDirty(boolean isDirty){\r
-               this.isDirty = isDirty;\r
-       }\r
-\r
-}\r
-\r
-\r
diff --git a/org.tizen.common/src/org/tizen/common/model/AbstractTableVO.java b/org.tizen.common/src/org/tizen/common/model/AbstractTableVO.java
deleted file mode 100644 (file)
index 8f359a6..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-public abstract class AbstractTableVO implements ITableVO{\r
-       public abstract String[] getColumnNames();\r
-       public abstract Object getColumnValue(int index);\r
-       public abstract void setColumnValue(int index, Object value);\r
-       \r
-       public AbstractTableVO clone(){\r
-               Object obj = null;\r
-               try{\r
-                       obj = super.clone();\r
-               }catch(CloneNotSupportedException e){\r
-                       \r
-               }\r
-               return (AbstractTableVO)obj;\r
-       }\r
-       \r
-       public Object getColumnValue(String columnName){\r
-               return getColumnValue(getColumnIndex(columnName));\r
-       }\r
-       \r
-       public String getColumnName(int index){\r
-               String[] columnNames = getColumnNames();\r
-               if(index<0||index>columnNames.length)\r
-                       return null;\r
-               else\r
-                       return columnNames[index];\r
-       }\r
-       \r
-       public int getColumnIndex(String columnName){\r
-               String[] columnNames = getColumnNames();\r
-               int index =-1;\r
-               for(int i=0;i<columnNames.length;i++){\r
-                       if(columnName.equals(columnNames[i])){\r
-                               index = i;\r
-                               break;\r
-                       }\r
-               }\r
-               return index;\r
-       }\r
-       \r
-       @Override\r
-       public String toString() {\r
-               StringBuffer buf = new StringBuffer();\r
-               String[] fields = getColumnNames();\r
-               for (int j = 0; j < fields.length; j++) {\r
-                       Object obj = getColumnValue(j);\r
-                       buf.append(obj==null?"":String.valueOf(obj)); //$NON-NLS-1$\r
-                       if(j<fields.length-1)\r
-                               buf.append(","); //$NON-NLS-1$\r
-               }\r
-               return buf.toString();\r
-       }\r
-       \r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/model/AbstractTreeModel.java b/org.tizen.common/src/org/tizen/common/model/AbstractTreeModel.java
deleted file mode 100644 (file)
index 0282ddf..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-\r
-import org.eclipse.ui.XMLMemento;\r
-\r
-public class AbstractTreeModel implements ITreeModel {\r
-       private static final String TAG_ROOT = "root"; //$NON-NLS-1$\r
-\r
-       private Collection<ITreeVO> inventory = new ArrayList<ITreeVO>();\r
-       protected ITreeVO source;\r
-       private boolean isDirty = false;\r
-\r
-       public AbstractTreeModel(ITreeVO source){\r
-//             if(source.getSuperclass() != ITreeVO.class)\r
-                       this.source = source;\r
-       }\r
-       \r
-       public ITreeVO[] getDatas() {\r
-               if (inventory == null)\r
-                       return null;\r
-\r
-               return inventory.toArray(new ITreeVO[inventory.size()]);\r
-       }\r
-\r
-       public void add(Collection<ITreeVO> datas) {\r
-               if (datas == null)\r
-                       return;\r
-\r
-               inventory.addAll(datas);\r
-       }\r
-       \r
-       public int size(){\r
-               return inventory.size();\r
-       }\r
-\r
-       public void add(ITreeVO data) {\r
-               inventory.add(data);\r
-       }\r
-\r
-       public void remove(Collection<ITreeVO> datas) {\r
-               if (datas == null)\r
-                       return;\r
-\r
-               inventory.removeAll(datas);\r
-       }\r
-\r
-       public void remove(ITreeVO data) {\r
-               inventory.remove(data);\r
-       }\r
-       \r
-       public void clear() {\r
-               inventory.clear();\r
-       }\r
-\r
-       public void load(String fileName) {\r
-       }\r
-\r
-       private void load(XMLMemento memento) {\r
-       }\r
-\r
-       public void save(String fileName) {\r
-       }\r
-\r
-       private void save(XMLMemento memento) {\r
-       }\r
-\r
-       public String getSourceName() {\r
-               return this.source.getClass().getSimpleName();\r
-       }\r
-\r
-\r
-       \r
-}\r
-\r
-\r
diff --git a/org.tizen.common/src/org/tizen/common/model/AbstractTreeVO.java b/org.tizen.common/src/org/tizen/common/model/AbstractTreeVO.java
deleted file mode 100644 (file)
index 8a7c0f0..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-import java.util.ArrayList;\r
-\r
-public abstract class AbstractTreeVO implements ITreeVO{\r
-\r
-       private String text;\r
-       private String description;\r
-       private Object data = null;\r
-       private int level = 0;\r
-       \r
-       private AbstractTreeVO parent;\r
-       private ArrayList<AbstractTreeVO> children;\r
-       \r
-       public AbstractTreeVO(AbstractTreeVO parent,String text) {\r
-               this.parent = parent;\r
-               this.text = text;\r
-               this.level = parent==null?1:parent.getLevel()+1;\r
-               if(parent!=null) \r
-                       parent.addChild(this);\r
-               children = new ArrayList<AbstractTreeVO>();\r
-       }\r
-       \r
-       public AbstractTreeVO(AbstractTreeVO parent) {\r
-               this(parent,null);\r
-       }\r
-       \r
-       public ITreeVO[] getChildren() {\r
-               return (ITreeVO[])children.toArray(new ITreeVO[children.size()]);\r
-       }\r
-       \r
-       public ITreeVO getParent(){\r
-               return this.parent;\r
-       }\r
-       \r
-       public boolean hasChildren() {\r
-               return children.size()>0;\r
-       }\r
-       \r
-       public int size() {\r
-               return children.size();\r
-       }\r
-       \r
-       public void addChild(ITreeVO child) {\r
-               children.add((AbstractTreeVO)child);\r
-       }\r
-       \r
-       public void removeChild(Object child) {\r
-               children.remove(child);\r
-       }\r
-       \r
-       public String toString() {\r
-               return getText();\r
-       }\r
-\r
-       public String getText() {\r
-               return text;\r
-       }\r
-\r
-       public void setText(String text) {\r
-               this.text = text;\r
-       }\r
-\r
-       public String getDescription() {\r
-               return description;\r
-       }\r
-\r
-       public void setDescription(String description) {\r
-               this.description = description;\r
-       }\r
-\r
-       public void setData(Object data) {\r
-               this.data = data;\r
-       }\r
-       \r
-       public Object getData(){\r
-               return this.data;\r
-       }\r
-       \r
-       public int getLevel(){\r
-               return this.level;\r
-       }\r
-       \r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/model/ITableModel.java b/org.tizen.common/src/org/tizen/common/model/ITableModel.java
deleted file mode 100644 (file)
index e21b41f..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-import java.util.Collection;\r
-\r
-\r
-public interface ITableModel\r
-{\r
-       public void add(AbstractTableVO datas);\r
-       public void add(Collection<AbstractTableVO> datas);\r
-       public void remove(AbstractTableVO datas);\r
-       public void remove(Collection<AbstractTableVO> datas);\r
-       public ITableVO[] getDatas();\r
-       public void load(String fileName);\r
-       public void save(String fileName);\r
-       public void clear();\r
-       public int size();\r
-       public String getSourceName();\r
-       public boolean isDirty();\r
-       public void setDirty(boolean isDirty);\r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/model/ITreeVO.java b/org.tizen.common/src/org/tizen/common/model/ITreeVO.java
deleted file mode 100644 (file)
index b0968aa..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-public interface ITreeVO extends IVO{\r
-       public ITreeVO[] getChildren();\r
-       public ITreeVO getParent();\r
-       public boolean hasChildren();\r
-       public int size();\r
-       public void addChild(ITreeVO child);\r
-       public void removeChild(Object child) ;\r
-       public String getText();\r
-       public void setText(String text);\r
-       public String getDescription();\r
-       public void setDescription(String description);\r
-       public void setData(Object data);\r
-       public Object getData();\r
-       public int getLevel();\r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/model/IVO.java b/org.tizen.common/src/org/tizen/common/model/IVO.java
deleted file mode 100644 (file)
index c49cf13..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-public interface IVO extends Cloneable{\r
-}\r
diff --git a/org.tizen.common/src/org/tizen/common/preferences/PreferenceMessages.properties b/org.tizen.common/src/org/tizen/common/preferences/PreferenceMessages.properties
deleted file mode 100644 (file)
index c4856e3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-TizenPreferencePage.0=General settings for Tizen developement:
-TizenPreferencePage.1=SDK Path settings
-TizenPreferencePage.2=Location:
-TizenPreferencePage.3=SDK Update
-TizenPreferencePage.4=Automatically find new updates and notify me
-
diff --git a/org.tizen.common/src/org/tizen/common/properties/InstallPathConfig.java b/org.tizen.common/src/org/tizen/common/properties/InstallPathConfig.java
deleted file mode 100644 (file)
index d49b708..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* 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.common.properties;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-import org.tizen.common.util.DialogUtil;
-import org.tizen.common.util.HostUtil;
-import org.tizen.common.util.OSChecker;
-
-
-
-final public class InstallPathConfig {
-        
-       private static String sdkInstallPath;
-       private final static String SDKSUFFIX = ".TizenSDK"+File.separatorChar+"tizensdkpath";
-       private final static String EMULATOR_PATH = "Emulator";
-       private final static String INSTALLER_PATH = "InstallManager";
-       
-       // Registry Key
-       private static final String REGISTRY_PATH_OF_SHELL_FOLDER = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
-       // public static final String REGISTRY_APP_DATA_OF_SHELL_FOLDER = "AppData";
-       private static final String REGISTRY_LOCAL_APP_DATA_OF_SHELL_FOLDER = "\"Local AppData\"";
-       // Value Column
-       private static final String REG_SZ = "REG_SZ";
-
-       static {
-               // FIXME : don't need the following lines if using environment variable 
-               String sdkPath;
-               
-               if (OSChecker.isWindows()) {
-                       String appdataPath = getRegistryValue(REGISTRY_PATH_OF_SHELL_FOLDER,REGISTRY_LOCAL_APP_DATA_OF_SHELL_FOLDER) ;
-                       sdkPath = appdataPath + File.separatorChar + SDKSUFFIX;                         
-                       loadSdkPath(sdkPath);
-               } else if (OSChecker.isLinux() == true || OSChecker.isUnix() == true || OSChecker.isMAC() == true) {
-                       sdkPath= System.getProperty("user.home") + File.separatorChar + SDKSUFFIX;      
-                       loadSdkPath(sdkPath);
-               } else {                        
-                       DialogUtil.openMessageDialog(System.getProperty("os.name") + " is not supported currently.");
-                       System.exit(0);
-               }
-       }
-       
-       public static String getEmulatorPath(){
-               return sdkInstallPath + File.separatorChar + EMULATOR_PATH;
-       }       
-       
-       /**
-        * @deprecated Use {@link #getSDKPath()} instead.
-        */
-       @Deprecated
-       public static String getIDEPath() { 
-               // FIXME : can't help but putting the code due to the Web IDE path , It has to be removed soon.
-               return System.getProperty("user.dir");          
-       }       
-       
-       public static String getSDKPath() {
-               return sdkInstallPath;
-       }
-
-       public static String getInstallManagerPath() {
-               return sdkInstallPath + File.separatorChar + INSTALLER_PATH;
-       }
-       
-       private static void loadSdkPath(String sdkPath) {
-               if (HostUtil.exists(sdkPath)) {
-                       String[] fileContent = HostUtil.getContents(sdkPath).split("=");
-                       if (HostUtil.exists(fileContent[1])) 
-                               sdkInstallPath = fileContent[1];
-                       else {
-                               DialogUtil.openMessageDialog("Tizen SDK is not installed propertly.");
-                               System.exit(0);
-                       }
-               } else {
-                       DialogUtil.openMessageDialog("Tizen SDK is not installed propertly.");
-                       System.exit(0);
-               }
-       }
-       private static String getRegistryValue(String node, String key) {
-               if (!OSChecker.isWindows())
-                       return null;
-               
-               BufferedReader br = null;
-               String value = "";
-               
-               String query = "reg query " + "\"" + node + "\" /v " + key;
-               try {
-                       Process process = Runtime.getRuntime().exec(query);                     
-                       String encoding = System.getProperty("sun.jnu.encoding");
-                       br = new BufferedReader(new InputStreamReader(process.getInputStream(), encoding));
-                       
-                       String line = null;
-                       while((line = br.readLine()) != null) {
-                               int index = line.indexOf(REG_SZ);
-                               if (index >= 0) {
-                                       value = line.substring(index + REG_SZ.length()).trim();
-                               }
-                       }
-               } catch (IOException e) {
-                       // TODO Auto-generated catch block
-                       e.printStackTrace();
-               } finally {
-                       if (br != null) {
-                               try {
-                                       br.close();
-                               } catch (IOException e) {
-                                       // TODO Auto-generated catch block
-                                       e.printStackTrace();
-                               }
-                       }
-               }
-               
-               return value;
-       }
-}
\ No newline at end of file
diff --git a/org.tizen.common/src/org/tizen/common/queue/Queue.java b/org.tizen.common/src/org/tizen/common/queue/Queue.java
deleted file mode 100644 (file)
index 366aba6..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* 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.common.queue;
-
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-public class Queue<T>{
-       
-       private ConcurrentLinkedQueue<T> queue = new ConcurrentLinkedQueue<T>();
-       private boolean waiting = false;
-       
-       public synchronized void add(T e){
-               queue.add(e);
-               if(waiting)
-                       notify();
-       }
-       
-       public synchronized T poll(){
-               while (isEmpty()) {
-                       try {
-                               waiting = true;
-                               wait();
-                       } catch (InterruptedException e) {
-                               e.printStackTrace();
-                       }
-               }
-               waiting = false;
-               return queue.poll();
-       }
-       
-       public synchronized void clear(){
-               queue.clear();
-       }
-       
-       public boolean isEmpty() {
-               return queue.isEmpty();
-       }
-
-       public int size() {
-               return queue.size();
-       }
-       
-       public synchronized void stop() {
-               if (waiting)
-                       notify();
-       }
-       
-}
  * - S-Core Co., Ltd
  */
 
-package org.tizen.common.swt;
+package org.tizen.common.ui;
 
 import org.eclipse.swt.graphics.Color;
-import org.eclipse.ui.PlatformUI;
+import org.tizen.common.util.cache.ColorCache;
 
 /**
- * Common SWT Color
+ *  Predefined Common SWT Color
+ * 
  * @author Gyeongseok Seo <gyeongseok.seo@samsung.com>
  *
  */
 public class CommonColor {
-       public static final Color BLACK = new Color(PlatformUI.getWorkbench().getDisplay(), 0, 0, 0);
-       public static final Color RED = new Color(PlatformUI.getWorkbench().getDisplay(), 255, 0, 0);
-       public static final Color ORANGE_RED = new Color(PlatformUI.getWorkbench().getDisplay(), 255, 69, 0);
-       public static final Color ROYAL_BLUE = new Color(PlatformUI.getWorkbench().getDisplay(), 65, 105, 225);
-       public static final Color YELLOW_GREEN = new Color(PlatformUI.getWorkbench().getDisplay(), 153, 204, 50);
+       public static final Color BLACK = ColorCache.getBlack();
+       public static final Color RED = ColorCache.getColor( 255, 0, 0 );
+       public static final Color ORANGE_RED = ColorCache.getColor( 255, 69, 0 );
+       public static final Color ROYAL_BLUE = ColorCache.getColor( 65, 105, 225 );
+       public static final Color YELLOW = ColorCache.getColor( 255, 255, 0 );
+       public static final Color LIGHT_YELLOW = ColorCache.getColor( 255, 255, 224 );
+       public static final Color YELLOW_GREEN = ColorCache.getColor( 153, 204, 50 );
+       public static final Color DARK_GOLDENROD = ColorCache.getColor( 184, 134, 11 );
 }
diff --git a/org.tizen.common/src/org/tizen/common/ui/TableToolTipListener.java b/org.tizen.common/src/org/tizen/common/ui/TableToolTipListener.java
new file mode 100644 (file)
index 0000000..e49672a
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Ho Namkoong <ho.namkoong@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.common.ui;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.tizen.common.util.SWTUtil;
+
+/**
+ * TableToolTipListener
+ * 
+ * Add tool tip to the table
+ * 
+ * @author Ho Namkoong{@literal <ho.namkoong@samsung.com>} (S-Core)
+ */
+public abstract class TableToolTipListener implements Listener{
+
+    private Shell tip = null;
+    private Label label = null;
+    private Table table = null;
+
+    /**
+     * Gets tooltip text from tableitem.
+     * 
+     * @param item table item from which tooltip text is extracted.
+     * @return tooltip text
+     */
+    protected abstract String getLabelText(TableItem item);
+    
+    /**
+     * Constructor with target table
+     * 
+     * @param table will be added listener.
+     */
+    
+    public void setTable(Table table) {
+        this.table = table;
+    }
+    
+    @Override
+    public void handleEvent(Event event) {
+        int eventType = event.type;
+        
+        if(SWT.MouseMove == eventType || SWT.MouseWheel == eventType || SWT.Dispose == eventType) {
+            if(tip != null) {
+                tip.dispose();
+                tip = null;
+                label = null;
+                return;
+            }
+        }
+        if(SWT.MouseHover == eventType) {
+            TableItem item = this.table.getItem(new Point(event.x, event.y));
+            if(item != null) {
+                if(tip != null && !tip.isDisposed()) {
+                    tip.dispose();
+                }
+                tip = new Shell(SWTUtil.getActiveShell(), SWT.ON_TOP | SWT.TOOL);
+                tip.setLayout(new FillLayout());
+                
+                label = new Label(tip, SWT.None);
+                label.setText(this.getLabelText(item));
+                label.setData(item);
+                
+                label.addListener(SWT.MouseExit, labelListener);
+                label.addListener(SWT.MouseDown, labelListener);
+                label.addListener(SWT.MouseWheel, labelListener);
+                
+                Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+                Rectangle rect = item.getBounds(0);
+                Point pt = this.table.toDisplay(rect.x, rect.y);
+                tip.setBounds(pt.x, pt.y, size.x, size.y);
+                tip.setVisible(true);
+            }
+        }
+    }
+    
+    final private Listener labelListener = new Listener() {
+        
+        @Override
+        public void handleEvent(Event event) {
+            Label label = (Label)event.widget;
+            Shell shell = label.getShell();
+            
+            int eventType = event.type;
+            if(SWT.MouseDown == eventType) {
+                if(table != null) {
+                    Event e = new Event();
+                    e.item = (TableItem) label.getData();
+                    
+                    table.setSelection((TableItem)e.item);
+                    table.notifyListeners(SWT.Selection, e);
+                }
+                return;
+            }
+            if(SWT.MouseExit == eventType || SWT.MouseWheel == eventType) {
+                shell.dispose();
+                return;
+            }
+        }
+    };
+}
@@ -23,7 +23,7 @@
 *
 */
 
-package org.tizen.common.swt;
+package org.tizen.common.ui.dialog;
 
 import org.eclipse.jface.action.ContributionItem;
 import org.eclipse.jface.action.ToolBarManager;
@@ -47,6 +47,7 @@ import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.swt.widgets.ToolItem;
+import org.tizen.common.util.SWTUtil;
 
 
 /**
@@ -60,7 +61,7 @@ public abstract class ClosableTray extends DialogTray {
        private Shell shell;
 
        private void createImages() {
-               Display display = Display.getCurrent();
+               Display display = SWTUtil.getDisplay();
                int[] shape = new int[] {
                                3, 3, 5, 3, 7, 5, 8, 5, 10, 3, 12, 3, 12, 5, 10, 7, 10, 8, 12, 10,
                                12, 12, 10, 12, 8, 10, 7, 10, 5, 12, 3, 12, 3, 10, 5, 8, 5, 7, 3, 5
@@ -169,4 +170,4 @@ public abstract class ClosableTray extends DialogTray {
                        closeHover.dispose();
                }
        }
-}
\ No newline at end of file
+}
diff --git a/org.tizen.common/src/org/tizen/common/ui/dialog/PasswordInputDialog.java b/org.tizen.common/src/org/tizen/common/ui/dialog/PasswordInputDialog.java
new file mode 100644 (file)
index 0000000..0229496
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Common
+ *
+ * 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.common.ui.dialog;
+
+import static org.tizen.common.util.SWTUtil.getActiveShell;
+import static org.tizen.common.util.StringUtil.EMPTY_STRING;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * <p>
+ * PasswordInputDialog.
+ * 
+ * Dialog for password input
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+PasswordInputDialog
+extends InputDialog
+{
+       /**
+        * Constructor with title, message
+        * 
+        * @param dialogTitle title of dialog
+        * @param dialogMessage message of dialog
+        * 
+        * @see #PasswordInputDialog(Shell, String, String)
+        */
+
+       public
+       PasswordInputDialog(
+               final String dialogTitle,
+               final String dialogMessage
+       )
+       {
+               this( getActiveShell(), dialogTitle, dialogMessage );
+       }
+
+       /**
+        * Constructor with shell, title, message
+        * 
+        * @param parentShell parent of dialog shell
+        * @param dialogTitle title of dialog
+        * @param dialogMessage message of dialog
+        * 
+        * @see #PasswordInputDialog(Shell, String, String, IInputValidator)
+        */
+       public
+       PasswordInputDialog(
+               final Shell parentShell,
+               final String dialogTitle,
+               final String dialogMessage
+       )
+       {
+               this( parentShell, dialogTitle, dialogMessage, null );
+       }
+
+       /**
+        * Constructor with shell, title, message and input validator
+        * 
+        * @param parentShell parent of dialog shell
+        * @param dialogTitle title of dialog
+        * @param dialogMessage message of dialog
+        * @param validator validator for input
+        */
+       public
+       PasswordInputDialog(
+               final Shell parentShell,
+               final String dialogTitle,
+               final String dialogMessage,
+               final IInputValidator validator
+       )
+       {
+               super( parentShell, dialogTitle, dialogMessage, EMPTY_STRING, validator );
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.dialogs.InputDialog#getInputTextStyle()
+        */
+       @Override
+       protected
+       int
+       getInputTextStyle()
+       {
+               return SWT.SINGLE | SWT.BORDER | SWT.PASSWORD;
+       }
+}
\ No newline at end of file
 * - S-Core Co., Ltd
 *
 */
-
-package org.tizen.common.manager;
+package org.tizen.common.ui.page.preference;
 
 import org.eclipse.osgi.util.NLS;
 
-public class Messages extends NLS {
-       private static final String BUNDLE_NAME = "org.tizen.common.manager.messages"; //$NON-NLS-1$
-       public static String ColorCache_0;
+public class Messages {
+
+       private static final String BUNDLE_NAME = Messages.class.getName();//$NON-NLS-1$
+
+       public static String DESCRIPTION;
+       
+       public static String GROUP1;
+       public static String GROUP2;
+       
+       public static String LABEL_LOCATION;
+       public static String LABEL_UPDATE;
+       
        static {
                // initialize resource bundle
-               NLS.initializeMessages(BUNDLE_NAME, Messages.class);
-       }
-
-       private Messages() {
+               NLS.initializeMessages( BUNDLE_NAME, Messages.class );
        }
 }
diff --git a/org.tizen.common/src/org/tizen/common/ui/page/preference/Messages.properties b/org.tizen.common/src/org/tizen/common/ui/page/preference/Messages.properties
new file mode 100644 (file)
index 0000000..b26e800
--- /dev/null
@@ -0,0 +1,5 @@
+DESCRIPTION=General settings
+GROUP1=SDK path
+LABEL_LOCATION=Location:
+GROUP2=SDK update
+LABEL_UPDATE=Automatically find new updates at start-up and notify me
diff --git a/org.tizen.common/src/org/tizen/common/ui/page/preference/PreferenceMessages.properties b/org.tizen.common/src/org/tizen/common/ui/page/preference/PreferenceMessages.properties
new file mode 100644 (file)
index 0000000..d91c289
--- /dev/null
@@ -0,0 +1,5 @@
+TizenPreferencePage.0=General settings
+TizenPreferencePage.1=SDK path
+TizenPreferencePage.2=Location:
+TizenPreferencePage.3=SDK update
+TizenPreferencePage.4=Automatically find new updates at start-up and notify me
@@ -23,7 +23,7 @@
 *
 */
 
-package org.tizen.common.preferences;
+package org.tizen.common.ui.page.preference;
 
 import org.eclipse.jface.preference.BooleanFieldEditor;
 import org.eclipse.jface.preference.DirectoryFieldEditor;
@@ -39,21 +39,24 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
 import org.tizen.common.CommonPlugin;
 
 
-public class TizenBasePreferencePage  extends FieldEditorPreferencePage  implements
-               IWorkbenchPreferencePage {
+public class
+TizenBasePreferencePage
+extends FieldEditorPreferencePage 
+implements IWorkbenchPreferencePage
+{
        
        public final static String TIZENSDK_PATH = CommonPlugin.PLUGIN_ID + ".TizenSDKBasePreferencePage"; //$NON-NLS-1$
        
        public static final String KEY_SDKLOCATION = "sdkpath"; //$NON-NLS-1$
        public static final String KEY_SDKUPDATE = "sdkupdate"; //$NON-NLS-1$
        public static final String VALUE_SDKLOCATION_DEFAULT = null;;
-       public static final boolean VALUE_SDKUPDATE_DEFAULT = true;
+       public static final boolean VALUE_SDKUPDATE_DEFAULT = false;
        
     public TizenBasePreferencePage() {
        //super(GRID);
                setPreferenceStore( CommonPlugin.getDefault().getPreferenceStore() );
                //getPreferenceStore().addPropertyChangeListener( getPropertyChangeListener() );
-               setDescription( PreferenceMessages.getString( "TizenPreferencePage.0" ) ); 
+               setDescription( Messages.DESCRIPTION ); 
     }
 
     
@@ -64,7 +67,6 @@ public class TizenBasePreferencePage  extends FieldEditorPreferencePage  impleme
        
        @Override
        protected void createFieldEditors() {
-               // TODO Auto-generated method stub
                Composite composite = getFieldEditorParent();
                
                GridLayout layout = new GridLayout();
@@ -90,16 +92,16 @@ public class TizenBasePreferencePage  extends FieldEditorPreferencePage  impleme
        }
        
        private void createPathSettingPreferences( Composite parent ) {
-               Composite comp = createGroup( parent, PreferenceMessages.getString( "TizenPreferencePage.1" ),1 ); //$NON-NLS-1$
+               Composite comp = createGroup( parent, Messages.GROUP1, 1 );
                Composite formatComposite = createCompositeEx( comp, 1, GridData.FILL_HORIZONTAL);
-               DirectoryFieldEditor mDirectoryField = new DirectoryFieldEditor(TizenBasePreferencePage.KEY_SDKLOCATION, PreferenceMessages.getString("TizenPreferencePage.2"), formatComposite);
+               DirectoryFieldEditor mDirectoryField = new DirectoryFieldEditor(KEY_SDKLOCATION, Messages.LABEL_LOCATION, formatComposite);
                addField(mDirectoryField);
        }
        
        private void createUpdateSettingPreferences( Composite parent ) {
-               Composite comp = createGroup( parent, PreferenceMessages.getString( "TizenPreferencePage.3" ),1 ); //$NON-NLS-1$
+               Composite comp = createGroup( parent, Messages.GROUP2, 1 );
                Composite formatComposite = createCompositeEx( comp, 1, GridData.FILL_HORIZONTAL);
-               BooleanFieldEditor startupCheckEditor = new BooleanFieldEditor(TizenBasePreferencePage.KEY_SDKUPDATE, PreferenceMessages.getString("TizenPreferencePage.4"), formatComposite);
+               BooleanFieldEditor startupCheckEditor = new BooleanFieldEditor(KEY_SDKUPDATE, Messages.LABEL_UPDATE, formatComposite);
                addField(startupCheckEditor);
        }
        
@@ -23,7 +23,7 @@
 *
 */
 
-package org.tizen.common.swt;
+package org.tizen.common.ui.page.wizard;
 
 import org.eclipse.jface.dialogs.DialogTray;
 import org.eclipse.jface.dialogs.TrayDialog;
@@ -38,6 +38,7 @@ import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.tizen.common.ui.dialog.ClosableTray;
 
 
 /**
old mode 100644 (file)
new mode 100755 (executable)
similarity index 55%
rename from org.tizen.common/src/org/tizen/common/console/AnsicodeAdapter.java
rename to org.tizen.common/src/org/tizen/common/ui/view/console/AnsicodeAdapter.java
index 73a32ad..822d5ea
 * - S-Core Co., Ltd
 *
 */
-package org.tizen.common.console;
+package org.tizen.common.ui.view.console;
+
+import static org.tizen.common.util.SWTUtil.getDisplay;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import org.eclipse.swt.graphics.Color;
-import org.eclipse.ui.PlatformUI;
+import org.tizen.common.util.MapUtil;
 
 public class AnsicodeAdapter {
        public static final char ESCAPE = '\033'; // ANSI Escape Character that starts commands
        
-       public static final Color BLACK = new Color(PlatformUI.getWorkbench().getDisplay(), 0, 0, 0);                           //Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
-       public static final Color RED = new Color(PlatformUI.getWorkbench().getDisplay(), 255, 0, 0);                           //Display.getCurrent().getSystemColor(SWT.COLOR_RED);
-       public static final Color GREEN = new Color(PlatformUI.getWorkbench().getDisplay(), 0, 255, 0);                 //Display.getCurrent().getSystemColor(SWT.COLOR_GREEN);
-       public static final Color YELLOW = new Color(PlatformUI.getWorkbench().getDisplay(), 255, 255, 0);              //Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);
-       public static final Color BLUE = new Color(PlatformUI.getWorkbench().getDisplay(), 0,0,255);                            //Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);
-       public static final Color MAGENTA = new Color(PlatformUI.getWorkbench().getDisplay(), 255, 0, 255);     //Display.getCurrent().getSystemColor(SWT.COLOR_MAGENTA);
-       public static final Color CYAN = new Color(PlatformUI.getWorkbench().getDisplay(), 0,255, 255);                 //Display.getCurrent().getSystemColor(SWT.COLOR_CYAN);
-       public static final Color WHITE = new Color(PlatformUI.getWorkbench().getDisplay(), 255, 255, 255);     //Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
-       
-       public static final Color INTENSE_BLACK = new Color(PlatformUI.getWorkbench().getDisplay(), 0, 0, 0);   //Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
-       public static final Color INTENSE_RED = new Color(PlatformUI.getWorkbench().getDisplay(), 139, 0, 0);   //Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED);
-       public static final Color INTENSE_GREEN = new Color(PlatformUI.getWorkbench().getDisplay(), 0, 100, 0);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN);
-       public static final Color INTENSE_YELLOW = new Color(PlatformUI.getWorkbench().getDisplay(), 250,250,210);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_YELLOW);
-       public static final Color INTENSE_BLUE = new Color(PlatformUI.getWorkbench().getDisplay(), 0,0,139);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE);
-       public static final Color INTENSE_MAGENTA = new Color(PlatformUI.getWorkbench().getDisplay(), 139,0,139);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_MAGENTA);
-       public static final Color INTENSE_CYAN = new Color(PlatformUI.getWorkbench().getDisplay(), 0, 139, 139);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_CYAN);
-       public static final Color INTENSE_WHITE = new Color(PlatformUI.getWorkbench().getDisplay(), 245, 245, 245);//Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
+       public static final Color BLACK = new Color(getDisplay(), 0, 0, 0);                             //Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
+       public static final Color RED = new Color(getDisplay(), 255, 0, 0);                             //Display.getCurrent().getSystemColor(SWT.COLOR_RED);
+       public static final Color GREEN = new Color(getDisplay(), 0, 255, 0);                   //Display.getCurrent().getSystemColor(SWT.COLOR_GREEN);
+       public static final Color YELLOW = new Color(getDisplay(), 255, 255, 0);                //Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);
+       public static final Color BLUE = new Color(getDisplay(), 0,0,255);                              //Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);
+       public static final Color MAGENTA = new Color(getDisplay(), 255, 0, 255);       //Display.getCurrent().getSystemColor(SWT.COLOR_MAGENTA);
+       public static final Color CYAN = new Color(getDisplay(), 0,255, 255);                   //Display.getCurrent().getSystemColor(SWT.COLOR_CYAN);
+       public static final Color WHITE = new Color(getDisplay(), 255, 255, 255);       //Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
        
+       public static final Color INTENSE_BLACK = new Color(getDisplay(), 0, 0, 0);     //Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
+       public static final Color INTENSE_RED = new Color(getDisplay(), 139, 0, 0);     //Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED);
+       public static final Color INTENSE_GREEN = new Color(getDisplay(), 0, 100, 0);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN);
+       public static final Color INTENSE_YELLOW = new Color(getDisplay(), 250,250,210);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_YELLOW);
+       public static final Color INTENSE_BLUE = new Color(getDisplay(), 0,0,139);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE);
+       public static final Color INTENSE_MAGENTA = new Color(getDisplay(), 139,0,139);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_MAGENTA);
+       public static final Color INTENSE_CYAN = new Color(getDisplay(), 0, 139, 139);//Display.getCurrent().getSystemColor(SWT.COLOR_DARK_CYAN);
+       public static final Color INTENSE_WHITE = new Color(getDisplay(), 245, 245, 245);//Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
+
+    public static final Map<Integer, Color[]> CODE2COLOR = Collections.unmodifiableMap( MapUtil.<Integer, Color[]>asMap( new Object[][] {
+        new Object[] { 30, new Color[] { INTENSE_BLACK, BLACK } },
+        new Object[] { 31, new Color[] { INTENSE_RED, RED } },
+        new Object[] { 32, new Color[] { INTENSE_GREEN, GREEN } },
+        new Object[] { 33, new Color[] { INTENSE_YELLOW, YELLOW } },
+        new Object[] { 34, new Color[] { INTENSE_BLUE, BLUE } },
+        new Object[] { 35, new Color[] { INTENSE_MAGENTA, MAGENTA } },
+        new Object[] { 36, new Color[] { INTENSE_CYAN, CYAN } },
+        new Object[] { 37, new Color[] { INTENSE_WHITE, WHITE } },
+        new Object[] { 40, new Color[] { INTENSE_BLACK, BLACK } },
+        new Object[] { 41, new Color[] { INTENSE_RED, RED } },
+        new Object[] { 42, new Color[] { INTENSE_GREEN, GREEN } },
+        new Object[] { 43, new Color[] { INTENSE_YELLOW, YELLOW } },
+        new Object[] { 44, new Color[] { INTENSE_BLUE, BLUE } },
+        new Object[] { 45, new Color[] { INTENSE_MAGENTA, MAGENTA } },
+        new Object[] { 46, new Color[] { INTENSE_CYAN, CYAN } },
+        new Object[] { 47, new Color[] { INTENSE_WHITE, WHITE } },
+    } ) );
+
        private static int[] commands = {'m','n'}; //SGR , DSR 
        
        private static List<TextStyle> parseAnsiString(String ansiString) {
@@ -148,59 +171,16 @@ public class AnsicodeAdapter {
         }
         return color;
        }
+       
+           
+
        private static Color getColorFromANSICode(int code, boolean brighter) {
-        switch (code) {
-            case 30:
-            case 40:
-                if (brighter)
-                    return INTENSE_BLACK;
-                else
-                    return BLACK;
-            case 31:
-            case 41:
-                if (brighter)
-                    return INTENSE_RED;
-                else
-                    return RED;
-            case 32:
-            case 42:
-                if (brighter)
-                    return INTENSE_GREEN;
-                else
-                    return GREEN;
-            case 33:
-            case 43:
-                if (brighter)
-                    return INTENSE_YELLOW;
-                else
-                    return YELLOW;
-            case 34:
-            case 44:
-                if (brighter)
-                    return INTENSE_BLUE;
-                else
-                    return BLUE;
-            case 35:
-            case 45:
-                if (brighter)
-                    return INTENSE_MAGENTA;
-                else
-                    return MAGENTA;
-            case 36:
-            case 46:
-                if (brighter)
-                    return INTENSE_CYAN;
-                else
-                    return CYAN;
-            case 37:
-            case 47:
-                if (brighter)
-                    return INTENSE_WHITE;
-                else
-                    return WHITE;
-            default:
-                return null;
-        }
+           final Color[] colorSet = CODE2COLOR.get( code );
+           if ( null == colorSet )
+           {
+               return null;
+           }
+           return colorSet[brighter?0:1];
     }
        public static String getStripAnsiString(String newLineStr) {
                List<TextStyle> styles = parseAnsiString(newLineStr);           
@@ -23,7 +23,7 @@
 * - S-Core Co., Ltd
 *
 */
-package org.tizen.common.console;
+package org.tizen.common.ui.view.console;
 import java.io.IOException;
 import java.lang.reflect.Method;
 
@@ -48,6 +48,7 @@ import org.eclipse.ui.console.MessageConsoleStream;
  * @author GyeongSeok Seo {@literal <gyeongseok.seo@samsung.com>} (S-Core)
  */
 public class ConsoleManager
+implements IConsolePrinter
 {
        private IConsoleManager consoleManager;
        private String consoleName;
@@ -248,10 +249,10 @@ public class ConsoleManager
                                IConsoleView view = null;
                                try {
                                        view = (IConsoleView) page.showView(id);
+                                       view.display(getConsole());
                                } catch (PartInitException e) {
                                         ConsolePlugin.log(e);
                                }
-                               view.display(getConsole());
                        }
                };
                Display.getDefault().syncExec(runnable);        
diff --git a/org.tizen.common/src/org/tizen/common/ui/view/console/ConsoleManager2.java b/org.tizen.common/src/org/tizen/common/ui/view/console/ConsoleManager2.java
new file mode 100644 (file)
index 0000000..d9fa7f7
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Yoonki Park <yoonki.park@samsung.com>
+* 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.common.ui.view.console;
+
+import static org.tizen.common.util.SWTUtil.asyncExec;
+import static org.tizen.common.util.SWTUtil.getActivePage;
+import static org.tizen.common.util.SWTUtil.syncExec;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleConstants;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.IConsoleView;
+import org.eclipse.ui.console.MessageConsoleStream;
+
+/**
+ * ConsoleManager2.
+ * 
+ * {@link MessageConsole}'s delegater
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+ConsoleManager2
+implements IConsolePrinter, IHyperlinkManager
+{
+       
+       /**
+        * MessageConsole to be delegated
+        */
+       protected final MessageConsoleSpy console;
+       
+       /**
+        * Link manager
+        */
+       protected final HyperlinkManager hyperlinkManager;
+       
+       /**
+        * console's name
+        * 
+        * @see {@link IConsole#setName(String)}
+        */
+       private String consoleName;
+       
+       /**
+        * document model's virtual length
+        */
+       protected int documentLength = 0;
+       
+       /**
+        * Constructs a new console manager.
+        * 
+        * @param consoleName - the key title 
+        * @param focus - true if focus on console, false if not
+        */
+       public
+       ConsoleManager2(
+               final String consoleName,
+               final boolean focus
+       )
+       {
+               this.console = createMessageConsole();
+               this.hyperlinkManager = new HyperlinkManager( console );
+               this.console.getDocument().addDocumentListener( hyperlinkManager );
+               
+               if ( focus )
+               {
+                       getConsoleManager().showConsoleView(console);
+               }
+               
+               setName( consoleName );
+       }
+       
+       /**
+        * return {@link IConsoleManager} from {@link ConsolePlugin}
+        * 
+        * @return {@link IConsoleManager}
+        * 
+        * @see ConsolePlugin#getConsoleManager()
+        */
+       protected IConsoleManager getConsoleManager()
+       {
+               return ConsolePlugin.getDefault().getConsoleManager();
+       }
+       
+       /**
+        * return <code>IConsole</code>s to be attached to {@link IConsoleManager}
+        * 
+        * @return <code>IConsole</code>s
+        * 
+        * @see #getConsoleManager()
+        * @see IConsoleManager#getConsoles()
+        */
+       protected IConsole[] getConsoles()
+       {
+               return getConsoleManager().getConsoles();
+       }
+       
+
+       /**
+        * Change Console Name.
+        *
+        * @param newName - console Title. It shown console's tab bar. 
+        * @author Gyeongseok.seo@samsung.com
+        */
+       public void
+       setName(
+               final String newName
+       )
+       {
+               if ( null == newName )
+               {
+                       throw new NullPointerException();
+               }
+               this.consoleName = newName;
+               asyncExec( new Runnable()
+               {
+                       public void run()
+                       {
+                               if ( null == console )
+                               {
+                                       return ;
+                               }
+                               console.setName(newName);
+                       }
+               } );
+       }
+       
+       /**
+        * Create message console
+        * 
+        * @return Message console for emulator
+        */
+       synchronized protected MessageConsoleSpy createMessageConsole()
+       {
+               // Delete Old Console from console view
+               final IConsole[] consoles = getConsoles();
+               for ( int i = 0, n = consoles.length ; i < n ; ++i )
+               {
+                       if ( !this.consoleName.equals(consoles[i].getName() ) )
+                       {
+                               continue;
+                       }
+                       getConsoleManager().removeConsoles( new IConsole[] { console } );
+               }
+               final MessageConsoleSpy console = new MessageConsoleSpy( this.consoleName );
+               getConsoleManager().addConsoles( new IConsole[] { console } );
+               
+               return console;
+       }
+       
+       /**
+        * return {@link IConsole}
+        * 
+        * @return {@link IConsole} to be managed
+        */
+       protected IConsole getConsole() {
+               return this.console;
+       }
+       
+       /**
+        * print <code>line</code> out to {@link IConsole} with line separator
+        * 
+        * @param line text to print
+        */
+       synchronized public void println(String line) {
+               final MessageConsoleStream output = createConsoleStream();
+               
+               try
+               {
+                       output.println( line );
+                       documentLength += ( line.length() + 1 );
+                       
+               } finally
+               {
+                       tryClose( output );
+               }
+       }
+       
+       /**
+        * Print out using {@link Process}
+        * @param process
+        */
+       public void printProcessStreams( final Process process) {
+               
+               clear();
+               // waitAndRead while process is running
+               ConsoleProcessClosure closure = new ConsoleProcessClosure(process, this);
+               
+               closure.runBlocking(); // a blocking cal
+       }
+       
+       
+       /**
+        * Return configured <code>MessageConsoleStream</code> 
+        * 
+        * with <code>fontStyle</code> and <code>color</code>
+        * 
+        * @param fontStyle SWT font style like {@link SWT#BOLD}, {@link SWT#ITALIC}, and etc.
+        * @param color color of message to be printed
+        * 
+        * @return configured <code>MessageConsoleStream</code>
+        * 
+        * @see #configureConsole(MessageConsoleStream, int, Color)
+        */
+       protected
+       MessageConsoleStream
+       getConsoleStream(
+               final int fontStyle,
+               final Color color
+       )
+       {
+               final MessageConsoleStream stream = createConsoleStream();
+               
+               configureConsole( stream, fontStyle, color );
+               
+               return stream;
+       }
+       
+       
+       /**
+        * Factory method for <code>MessageConsoleStream</code>
+        * 
+        * @return <code>MessageConsoleStream</code> to be created
+        * 
+        * @see MessageConsole#newMessageStream()
+        */
+       protected
+       MessageConsoleStream
+       createConsoleStream()
+       {
+               final MessageConsoleStream stream = console.newMessageStream();
+               
+               return stream;
+       }
+       
+       /**
+        * Configure <code>stream</code> with <code>fontStyle</code> and <code>color</code>
+        * 
+        * @param stream <code>MessageConsoleStream</code> to configure
+        * @param fontStyle SWT font style
+        * @param color
+        * 
+        * @see SWT#NORMAL
+        * @see SWT#BOLD
+        * @see SWT#ITALIC
+        */
+       protected void
+       configureConsole(
+               final MessageConsoleStream stream,
+               final int fontStyle,
+               final Color color
+       )
+       {
+               syncExec( new Runnable()
+               {
+                       public void run()
+                       {
+                       // font setting
+                               stream.setFontStyle( fontStyle );
+
+                       // color setting
+                               stream.setColor( color );
+                       }
+               } );
+       }
+
+       /**
+        * print out <code>message</code> with <code>fontStyle</code> and <code>color</code>
+        * 
+        * @param message message to print out
+        * @param fontStyle SWT font style
+        * @param color color of message
+        */
+       synchronized public
+       void
+       print(
+               final String message,
+               final int fontStyle,
+               final Color color
+       )
+       {
+               final MessageConsoleStream stream = getConsoleStream( fontStyle, color );
+               try
+               {
+                       stream.print(message);
+                       documentLength += (message.length() );
+               }
+               finally
+               {
+                       tryClose( stream );
+               }
+       }
+
+       /**
+        * print out with line separator
+        * 
+        * @param message message to print out
+        * @param fontStyle font style
+        * @param color color
+        * 
+        * @see #print(String, int, Color)
+        */
+       public
+       void
+       println(
+               final String message,
+               final int fontStyle,
+               final Color color
+       )
+       {
+               print( message + "\n", fontStyle, color );
+       }
+       
+       /**
+        * clear message console
+        */
+       synchronized public
+       void
+       clear()
+       {
+               syncExec(
+                       new Runnable() {
+                               public void run() {
+                                       IDocument document = console.getDocument();
+                                       if ( null == document )
+                                       {
+                                               return ;
+                                       }
+                                       document.set("");
+                               }
+                       }
+               );
+               documentLength = 0;
+       }
+       
+       /**
+        * Activate console
+        */
+       public
+       void
+       show()
+       {
+               syncExec(
+                       new Runnable() {
+                               public void run() {
+                                       final IWorkbenchPage page = getActivePage();
+                                       if ( null == page )
+                                       {
+                                               // How to handle no active page( no view page )
+                                               throw new IllegalStateException();
+                                       }
+                                       try {
+                                               IConsoleView view = (IConsoleView) page.showView( IConsoleConstants.ID_CONSOLE_VIEW );
+                                               view.display(getConsole());
+                                       } catch (
+                                               final PartInitException e
+                                       )
+                                       {
+                                                ConsolePlugin.log(e);
+                                       }
+                               }
+                       }
+               );      
+       }
+       
+       /* (non-Javadoc)
+        * @see org.tizen.common.console.IHyperlinkerManager#addLinker(org.tizen.common.console.LinkInfo)
+        */
+       @Override
+       public
+       void
+       addLinker(
+               final LinkInfo link
+       )
+       {
+               hyperlinkManager.addLinker( link );
+       }
+
+}
+
 * - S-Core Co., Ltd
 *
 */
-package org.tizen.common.console;
+package org.tizen.common.ui.view.console;
+
+import static org.tizen.common.util.IOUtil.tryClose;
 
 import java.io.BufferedReader;
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -44,16 +47,18 @@ public class ConsoleProcessClosure {
         * Thread which continuously reads from a input stream and pushes the read
         * data to an output stream which is immediately flushed afterwards.
         */
-       protected static class ReaderThread extends Thread {
+       protected static class ReaderThread
+       extends Thread
+       implements Closeable {
 
                private InputStream fInputStream;
-               private ConsoleManager fConsole;
+               private IConsolePrinter fConsole;
                private boolean fFinished = false;
                private String lineSeparator;
                /*
                 * outputStream can be null
                 */
-               public ReaderThread(ThreadGroup group, String name, InputStream in, ConsoleManager out) {
+               public ReaderThread(ThreadGroup group, String name, InputStream in, IConsolePrinter out) {
                        super(group, name);
                        fConsole = out;
                        fInputStream = in;
@@ -82,11 +87,7 @@ public class ConsoleProcessClosure {
                                } catch (IOException x) {
                                        // ignore
                                } finally {
-                                       try {
-                                               fInputStream.close();
-                                       } catch (IOException e) {
-                                               // ignore
-                                       }
+                                       tryClose( fInputStream );
                                }
                        } finally {
                                complete();
@@ -124,7 +125,7 @@ public class ConsoleProcessClosure {
        protected static int fCounter = 0;
 
        protected Process fProcess;
-       protected ConsoleManager fConsole;
+       protected IConsolePrinter fConsole;
 
        protected ReaderThread fOutputReader;
        protected ReaderThread fErrorReader;
@@ -140,7 +141,7 @@ public class ConsoleProcessClosure {
         *            prcess stderr is written to this stream. Can be
         *            <code>null</code>, if not interested in reading the output
         */
-       public ConsoleProcessClosure(Process process, ConsoleManager console) {
+       public ConsoleProcessClosure(Process process, IConsolePrinter console) {
                fProcess = process;
                fConsole = console;
        }
@@ -189,8 +190,7 @@ public class ConsoleProcessClosure {
                        fErrorReader.waitFor();
                }
 
-               fOutputReader.close();
-               fErrorReader.close();
+               tryClose( fOutputReader, fErrorReader );
                // it seems that thread termination and stream closing is working
                // without
                // any help
@@ -205,10 +205,7 @@ public class ConsoleProcessClosure {
                                return true;
                        }
                        fProcess = null;
-                       fOutputReader.close();
-                       fErrorReader.close();
-                       fOutputReader = null;
-                       fErrorReader = null;
+                       tryClose( fOutputReader, fErrorReader );
                }
                return false;
        }
@@ -241,10 +238,7 @@ public class ConsoleProcessClosure {
                if (!fErrorReader.finished()) {
                        fErrorReader.waitFor();
                }
-               fOutputReader.close();
-               fErrorReader.close();
-               fOutputReader = null;
-               fErrorReader = null;
+               tryClose( fOutputReader, fErrorReader );
        }
 }
 
diff --git a/org.tizen.common/src/org/tizen/common/ui/view/console/HyperlinkManager.java b/org.tizen.common/src/org/tizen/common/ui/view/console/HyperlinkManager.java
new file mode 100644 (file)
index 0000000..be32de9
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+*  Common
+*
+* 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.common.ui.view.console;
+
+import java.util.Iterator;
+import java.util.TreeSet;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.ui.console.TextConsole;
+
+/**
+ * HyperlinkManager.
+ * 
+ * Manage hyperlink. 
+ * 
+ * process deferedly because {@link TextConsole} is asynchronous.
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+HyperlinkManager
+implements IHyperlinkManager, IDocumentListener
+{
+       /**
+        * {@link TextConsole} to connect link
+        */
+       protected TextConsole console;
+
+       /**
+        * unconnected links
+        */
+       protected final TreeSet<LinkInfo> dangledLinks = new TreeSet<LinkInfo>();
+       
+       /**
+        * Constructor with {@link TextConsole} to connect link
+        * 
+        * @param console {@link TextConsole} to connect link
+        */
+       public
+       HyperlinkManager(
+               final TextConsole console
+       )
+       {
+               this.console = console;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+        */
+       @Override
+       public
+       void
+       documentAboutToBeChanged(
+               final DocumentEvent event
+       )
+       {
+               // Not implement
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+        */
+       @Override
+       public
+       void
+       documentChanged(
+               final DocumentEvent event
+       )
+       {
+               final IDocument doc = event.getDocument();
+               final int docLen = doc.getLength();
+               
+               for ( final Iterator<LinkInfo> iter = dangledLinks.iterator() ; iter.hasNext() ; )
+               {
+                       final LinkInfo info = iter.next();
+                       
+                       if (  docLen < info.getEnd() )
+                       {
+                               return ;
+                       }
+                       
+                       try
+                       {
+                               this.console.addHyperlink( info.getLink(), info.getStart(), info.getLength() );
+                               iter.remove();
+                       } catch ( final BadLocationException e )
+                       {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.console.IHyperlinkerManager#addLinker(org.tizen.common.console.LinkInfo)
+        */
+       @Override
+       public
+       void
+       addLinker(
+               final LinkInfo link
+       )
+       {
+               dangledLinks.add( link );
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/ui/view/console/IConsolePrinter.java b/org.tizen.common/src/org/tizen/common/ui/view/console/IConsolePrinter.java
new file mode 100644 (file)
index 0000000..efa154a
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+*  Common
+*
+* 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.common.ui.view.console;
+
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * IConsolePrinter.
+ * 
+ * {@link IConsoleManager}'s adaptation interface
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface IConsolePrinter
+{
+       /**
+        * print line out to {@link IConsole}
+        * 
+        * @param msg message to print out
+        * @param fontStyle font style flag
+        * @param color foreground color of <code>msg</code> to print out 
+        */
+       void print( String msg, int fontStyle, Color color );
+}
@@ -1,35 +1,46 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-public interface ITableVO extends IVO{\r
-       public String[] getColumnNames();\r
-       public Object getColumnValue(int index);\r
-       public Object getColumnValue(String columnName);\r
-       public int getColumnIndex(String columnName);\r
-       public String getColumnName(int index);\r
-       public void setColumnValue(int index, Object value);\r
-}\r
+/*
+*  Common
+*
+* 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.common.ui.view.console;
+
+
+/**
+ * IHyperlinkerManager.
+ * 
+ * Manage hyperlinks in asynchronous stream
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface
+IHyperlinkManager
+{
+       /**
+        * add <code>link</code> to IConsole
+        * 
+        * @param link hyper link's info
+        * 
+        * @see LinkInfo
+        */
+       void addLinker( LinkInfo link );
+}
diff --git a/org.tizen.common/src/org/tizen/common/ui/view/console/LinkInfo.java b/org.tizen.common/src/org/tizen/common/ui/view/console/LinkInfo.java
new file mode 100644 (file)
index 0000000..9eb0bbc
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+*  Common
+*
+* 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.common.ui.view.console;
+
+import org.eclipse.ui.console.IHyperlink;
+
+/**
+ * LinkInfo.
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+LinkInfo
+implements Comparable<LinkInfo>
+{
+       /**
+        * Link's start offset
+        */
+       protected final int offset;
+       
+       /**
+        * Link's textual length
+        */
+       protected final int length;
+       
+       /**
+        * <code>IHyperlink</code> to connect
+        */
+       protected final IHyperlink link;
+       
+       /**
+        * Constructor with link's offset, length and hyperlink
+        * 
+        * @param offset link's start offset
+        * @param length link's length
+        * @param link hyperlink
+        */
+       public LinkInfo(
+               final int offset,
+               final int length,
+               final IHyperlink link
+       )
+       {
+               this.offset = offset;
+               this.length = length;
+               this.link = link;
+               if ( length < 0 )
+               {
+                       throw new IllegalArgumentException( "Link's length is negative :" + this );
+               }
+       }
+       
+       /**
+        * Return link's start position in text
+        * 
+        * @return link's start position
+        * 
+        * @see #getEnd()
+        * @see #getLength()
+        */
+       public
+       int
+       getStart()
+       {
+               return this.offset;
+       }
+       
+       /**
+        * Return link's end position in text
+        * 
+        * @return link's end position
+        * 
+        * @see #getStart()
+        * @see #getEnd()
+        */
+       public
+       int
+       getEnd()
+       {
+               return getStart() + getLength();
+       }
+       
+       /**
+        * Return link's length
+        * 
+        * @return link's length
+        * 
+        * @see #getStart();
+        * @see #getEnd();
+        */
+       public
+       int
+       getLength()
+       {
+               return this.length;
+       }
+       
+       /**
+        * return hyper link
+        * @return {@link IHyperlink}
+        */
+       public
+       IHyperlink
+       getLink()
+       {
+               return this.link;
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Comparable#compareTo(java.lang.Object)
+        */
+       @Override
+       public
+       int
+       compareTo(LinkInfo o)
+       {
+               return getLength() - o.getLength();
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public
+       String
+       toString()
+       {
+               return "Link(" + getStart() + ":" + getEnd() + ")-" + link;
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/ui/view/console/MessageConsoleSpy.java b/org.tizen.common/src/org/tizen/common/ui/view/console/MessageConsoleSpy.java
new file mode 100644 (file)
index 0000000..1a1a7df
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+*  Common
+*
+* 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.common.ui.view.console;
+
+import org.eclipse.ui.console.MessageConsole;
+
+public class
+MessageConsoleSpy
+extends MessageConsole
+{
+
+       /**
+        * Constructor with console name
+        * 
+        * @param name console's key title
+        */
+       public MessageConsoleSpy( final String name )
+       {
+               super( name, null );
+       }
+       
+       /**
+        * make {@link AbstractConsole#setName(String)} accessible
+        * 
+        * @see org.eclipse.ui.console.AbstractConsole#setName(java.lang.String)
+        */
+       public void setName( final String name )
+       {
+               super.setName( name );
+       }
+       
+       
+}
@@ -23,7 +23,7 @@
 *\r
 */\r
 \r
-package org.tizen.common.swt;\r
+package org.tizen.common.ui.widget;\r
 \r
 import java.util.List;\r
 import java.util.ArrayList;\r
@@ -191,6 +191,9 @@ public class PictureLabel extends Canvas {
 }\r
 \r
 class ImageClickedEvent extends java.util.EventObject {\r
+       \r
+       private static final long serialVersionUID = 2923125560667763769L;\r
+       \r
        public int x, y;\r
 \r
        public ImageClickedEvent(Object source, int x, int y) {\r
diff --git a/org.tizen.common/src/org/tizen/common/update/UpdateMessages.properties b/org.tizen.common/src/org/tizen/common/update/UpdateMessages.properties
deleted file mode 100644 (file)
index 06a30a9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-##
-message.dialogTitle = Tizen SDK
-message.askForUpdate = Updates are available for Tizen SDK. Do you want to install them?
\ No newline at end of file
diff --git a/org.tizen.common/src/org/tizen/common/util/ArrayUtil.java b/org.tizen.common/src/org/tizen/common/util/ArrayUtil.java
new file mode 100755 (executable)
index 0000000..ee1a571
--- /dev/null
@@ -0,0 +1,1124 @@
+/*
+ *  Common
+ *
+ * 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.common.util;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+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 );
+       }
+       
+       /**
+        * <p>
+        * run <code>runner</code> iterateing element of <code>array</code>.
+        * 
+        * use without null-check for <code>array</code>
+        * 
+        * delegate error handling to <code>array</code>
+        * </p>
+        * 
+        * <pre>
+        * 
+        * ArrayUtil.iterate(
+        *      Arrays.asList( "hello", "Hello", "World", null, "Test" ),
+        *      new IteratingRunner<String>() {
+        *              public void run( String arg ) {
+        *                      ...
+        *              }
+        *      }
+        * );
+        * 
+        * </pre>
+        * 
+        * @param <T> type of element in <code>array</code>
+        * @param array array containing element
+        * @param runner {@link Runnable} to execute
+        * 
+        * @throws InvocationTargetException when <code>runner</code>'s {@link Runnable#run()} throws exception 
+        * 
+        * @see {@link #iterate(Object[], IteratingRunner, boolean)}
+        * @see FilterIterator
+        */
+       public static <T>
+       void
+       iterate(
+               final T[] array,
+               final IteratingRunner<T> runner
+       )
+       {
+               try
+               {
+                       iterate( array, runner, true );
+               } catch ( final InvocationTargetException e)
+               {
+                       // Be never reached
+                       throw new IllegalStateException( e );
+               }
+       }
+       
+       /**
+        * <p>
+        * run <code>runner</code> iterateing element of <code>array</code>.
+        * 
+        * use without null-check for <code>array</code>
+        * 
+        * delegate error handling to <code>runner</code>
+        * 
+        * </p>
+        * <pre>
+        * 
+        * ArrayUtil.iterate(
+        *      Arrays.asList( "hello", "Hello", "World", null, "Test" ),
+        *      new IteratingRunner<String>() {
+        *              public void run( String arg ) {
+        *                      ...
+        *              }
+        *      },
+        *      true
+        * );
+        * 
+        * </pre>
+        * 
+        * @param <T> type of element in <code>array</code>
+        * @param array array containing element
+        * @param runner {@link Runnable} to execute
+        * @param bForceProcess flag to iterate continuously when exception occurs
+        * 
+        * @throws InvocationTargetException when <code>runner</code>'s {@link Runnable#run()} throws exception 
+        * 
+        * @see FilterIterator
+        */
+       public static <T>
+       void
+       iterate(
+               final T[] array,
+               final IteratingRunner<T> runner,
+               final boolean bForceProcess
+       )
+       throws InvocationTargetException
+       {
+               if ( null == runner )
+               {
+                       return ;
+               }
+               
+               for ( final T arg : safe( array ) )
+               {
+                       if ( null == arg && !bForceProcess )
+                       {
+                               continue ;
+                       }
+                       try
+                       {
+                               runner.run( arg );
+                       } catch ( Throwable e )
+                       {
+                               if ( !bForceProcess )
+                               {
+                                       throw new InvocationTargetException( e );
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * <p>
+        * Fiter <code>array</code> and return filtered array
+        * 
+        * Ignore exception in filtering logic
+        * </p>
+        * 
+        * @param <T> type of element in <code>array</code>
+        * @param array array to filter
+        * @param runner object to determine if filter
+        */
+       public static <T>
+       T[]
+       filter(
+               final T[] array,
+               final IteratingAcceptor<T> runner
+       )
+       {
+               try
+               {
+                       return filter( array, runner, true );
+               } catch ( final InvocationTargetException e )
+               {
+                       // Be never reached
+                       throw new IllegalStateException( e );
+               }
+       }
+       /**
+        * <p>
+        * Fiter <code>array</code> and return filtered array
+        * 
+        * determined if stop or keep going using <code>bForceProcess</code> in case of exception.
+        * </p>
+        * 
+        * @param <T> type of element in <code>array</code>
+        * @param array array to filter
+        * @param runner object to determine if filter
+        * @param bForceProcess flag to keep going when exception occurs
+        * 
+        * @throws InvocationTargetException when <code>runner</code>'s {@link IteratingAcceptor#accept(Object)} throws exception 
+        */
+       @SuppressWarnings("unchecked")
+       public static <T>
+       T[]
+       filter(
+               final T[] array,
+               final IteratingAcceptor<T> runner,
+               final boolean bForceProcess
+       ) throws InvocationTargetException
+       {
+               final ArrayList<T> list = new ArrayList<T>();
+               
+               for ( final T arg : safe( array ) )
+               {
+                       if ( null == arg && !bForceProcess )
+                       {
+                               continue ;
+                       }
+                       try
+                       {
+                               if ( runner.accept( arg ) )
+                               {
+                                       list.add( arg );
+                               }
+                       } catch ( Throwable e )
+                       {
+                               if ( !bForceProcess )
+                               {
+                                       throw new InvocationTargetException( e );
+                               }
+                       }
+
+               }
+               
+               return (T[]) list.toArray( newArray( array.getClass().getComponentType(), list.size() ) );
+       }
+
+       
+       /**
+        * 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
+       )
+       {
+               if ( null == array )
+               {
+                       throw new NullPointerException();
+               }
+               Assert.isTrue(
+                       start <= end,
+                       "start indnex(" + start + ") is greater than end index(" + end + ")"
+               );
+               
+               int startIndex = Math.max( 0, start );
+               int endIndex = Math.min( array.length, end );
+               if ( endIndex <= startIndex )
+               {
+                       return (T[]) array;
+               }
+               
+               final Class<?> compType = array.getClass().getComponentType();
+               
+               final int removeSize = endIndex - startIndex;
+
+               final int newArrLength = size( array ) - removeSize;
+               
+               final Object[] newArr = 
+                       (Object[]) Array.newInstance( compType, newArrLength );
+               
+               System.arraycopy( array, 0, newArr, 0, startIndex );
+               System.arraycopy( array, endIndex, newArr, startIndex, array.length-endIndex );
+               
+               return (T[]) newArr;
+       }
+
+       /**
+        * remove elements whose index is <code>index</code>
+        * 
+        * and return applied array
+        *
+        * @param <T> type of array element
+        * @param array array to remove elements
+        * @param index index to remove
+        * 
+        * @return change applied new array
+        * 
+        * @throws ArrayIndexOutOfBoundsException 
+        *              if <code>index</code> is not in range of array
+        */
+       public static <T> T[]
+       remove(
+               final Object[] array,
+               final int index
+       )
+       {
+               return remove( array, index, index + 1);
+       }
+
+       /**
+        * Check if <code>array</code> contains <code>element</code>
+        * 
+        * @param array array to check
+        * @param element object to check
+        * 
+        * @return <code>true</code> if <code>collection</code> contain <code>element</code>
+        */
+       public static <K, V>
+       boolean
+       contains(
+               final K[] array,
+               final V element
+       )
+       {
+               if ( null == array )
+               {
+                       return false;
+               }
+               
+               for ( final Object candidate : array )
+               {
+                       if ( ObjectUtil.equals( candidate, element ) )
+                       {
+                               return true; 
+                       }
+               }
+               return false;
+       }
+       
+       /**
+        * Return <code>index</code> th element in <code>collection</code>
+        * 
+        * Return <code>null</code> if <code>index</code> is out of range
+        * 
+        * @param <K> array type
+        * @param array array object to access
+        * @param index array index
+        * @return <code>index</code> th element in array
+        */
+       public static <K>
+       K
+       get(
+               final K[] array,
+               final int index
+       )
+       {
+               if ( null == array )
+               {
+                       return null;
+               }
+               if ( index < 0 )
+               {
+                       return null;
+               }
+               if ( array.length <= index )
+               {
+                       return null;
+               }
+               
+               return array[index];
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Boolean[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Boolean[] convertToWrapper( final boolean[] array )
+       {
+               final int nArray = size( array );
+               final Boolean[] ret = new Boolean[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Byte[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Byte[] convertToWrapper( final byte[] array )
+       {
+               final int nArray = size( array );
+               final Byte[] ret = new Byte[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+       
+       /**
+        * Convert <code>array</code> to {@link Character[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Character[] convertToWrapper( final char[] array )
+       {
+               final int nArray = size( array );
+               final Character[] ret = new Character[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+       
+       
+       /**
+        * Convert <code>array</code> to {@link Short[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Short[] convertToWrapper( final short[] array )
+       {
+               final int nArray = size( array );
+               final Short[] ret = new Short[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+       
+       /**
+        * Convert <code>array</code> to {@link Integer[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Integer[] convertToWrapper( final int[] array )
+       {
+               final int nArray = size( array );
+               final Integer[] ret = new Integer[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Long[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Long[] convertToWrapper( final long[] array )
+       {
+               final int nArray = size( array );
+               final Long[] ret = new Long[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Float[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Float[] convertToWrapper( final float[] array )
+       {
+               final int nArray = size( array );
+               final Float[] ret = new Float[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       /**
+        * Convert <code>array</code> to {@link Double[]}
+        * 
+        * @param array array to convert
+        * 
+        * @return converted array
+        */
+       public static Double[] convertToWrapper( final double[] array )
+       {
+               final int nArray = size( array );
+               final Double[] ret = new Double[nArray];
+               
+               for ( int i = 0 ; i < nArray ; ++i )
+               {
+                       ret[i] = array[i];
+               }
+               
+               return ret;
+       }
+
+       @SuppressWarnings("unchecked")
+    public static <T> T[] safe( T[] unsafe )
+       {
+           return (T[]) ObjectUtil.nvl( unsafe, EMPTY_OBJECT_ARRAY );
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/Assert.java b/org.tizen.common/src/org/tizen/common/util/Assert.java
new file mode 100755 (executable)
index 0000000..b9c4a0a
--- /dev/null
@@ -0,0 +1,837 @@
+/*
+*  Common
+*
+* 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.common.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, "" );
+       }
+
+}
index 87c3704..96111da 100644 (file)
@@ -25,6 +25,8 @@
 
 package org.tizen.common.util;
 
+import static org.tizen.common.util.SWTUtil.asyncExec;
+
 import java.io.File;
 
 import org.eclipse.swt.SWT;
@@ -52,8 +54,7 @@ public class BrowserWrapper {
     }
 
     public void setInput(final File f) {
-        browser.getDisplay().asyncExec(new Runnable() {
-            @Override
+        asyncExec(new Runnable() {
             public void run() {
                 if (!browser.isDisposed()) {
                     browser.setUrl(f.getAbsolutePath());
diff --git a/org.tizen.common/src/org/tizen/common/util/CipherUtil.java b/org.tizen.common/src/org/tizen/common/util/CipherUtil.java
new file mode 100644 (file)
index 0000000..6bf9a91
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Ho Namkoong <ho.namkoong@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.common.util;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESedeKeySpec;
+
+import org.tizen.common.util.log.Logger;
+
+import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
+
+/**
+ * CipherUtil 
+ * 
+ * This is a util class for encrypting and decrypting plain texts. 
+ *  
+ * @author Ho Namkoong{@literal <ho.namkoong@samsung.com>} (S-Core)
+ */
+public class CipherUtil {
+
+    private static final String password = "KYANINYLhijklmnopqrstuvwx";
+    private static SecretKey SECRETE_KEY;
+    private static Cipher DES_CIPHER;
+    private static final String ALGORITHM = "DESede";
+    
+    static {
+        try {
+            byte key[] = password.getBytes();
+            DESedeKeySpec desKeySpec = new DESedeKeySpec(key);
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
+            SECRETE_KEY = keyFactory.generateSecret(desKeySpec);
+            
+            DES_CIPHER = Cipher.getInstance(ALGORITHM + "/ECB/PKCS5Padding");
+        } catch (Throwable t) {
+            Logger.error("Exception occurred while creating secret key", t);
+        }
+    }
+    
+    private static byte[] decryptByDES(byte[] bytes) throws Exception{
+        DES_CIPHER.init(Cipher.DECRYPT_MODE, SECRETE_KEY);
+        
+        return DES_CIPHER.doFinal(bytes);
+    }
+    
+    private static byte[] encryptByDES(String s) throws Exception {
+        DES_CIPHER.init(Cipher.ENCRYPT_MODE, SECRETE_KEY);
+        
+        return DES_CIPHER.doFinal(s.getBytes());
+    }
+    
+    /**
+     * Decrypt cipher message 
+     *
+     * @param s cipher message which will be decrypted.
+     * @return decrypted plain text.
+     * @author Ho Namkoong {@literal <ho.namkoong@samsung.com>} (S-Core)
+     */
+    public static String getDecryptedString(String s) throws Exception {
+        return new String(decryptByDES(Base64.decode(s)));
+    }
+    
+    /**
+     * Encrypt plain text 
+     *
+     * @param s plain text which will be encrypted.
+     * @return encrypted cipher text.
+     * @author Ho Namkoong {@literal <ho.namkoong@samsung.com>} (S-Core)
+     */
+    public static String getEncryptedString(String s) throws Exception {
+        return new String(Base64.encode(encryptByDES(s)));
+    }
+}
\ No newline at end of file
diff --git a/org.tizen.common/src/org/tizen/common/util/CollectionMap.java b/org.tizen.common/src/org/tizen/common/util/CollectionMap.java
new file mode 100644 (file)
index 0000000..9037579
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ *  Common
+ *
+ * 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.common.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+
+
+/**
+ * CollectionUtil.
+ * 
+ * Helper related to collection( Set, List, etc )
+ * 
+ * Characters for both {@link Collection} and {@link Map}
+ * 
+ * You can add and remove not only key-value pair but also a set of key-value
+ * 
+ * Replace key-value set to <code>null</code> if no values
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @param <K> key type
+ * @param <V> value type
+ */
+public class
+CollectionMap<K, V>
+{
+
+       /**
+        * Map to manage key-values
+        */
+       protected final HashMap<K, Collection<V>> map = new LinkedHashMap<K, Collection<V>>();
+
+
+       /**
+        * Create values container
+        * 
+        * Determine a method for management of values
+        * 
+        * Modify this method if you want to change value container
+        * 
+        * @return value containing {@link Collection}
+        */
+       protected
+       Collection<V>
+       createValues()
+       {
+               return new ArrayList<V>();
+       }
+
+       /**
+        * Add key-value pair
+        * 
+        * @param key key to add 
+        * @param value value to add
+        */
+       public
+       void
+       put(
+               final K key,
+               final V value
+       )
+       {
+               Collection<V> values = map.get( key );
+               if ( null == values )
+               {
+                       values = createValues();
+                       map.put( key, values );
+               }
+
+               values.add( value );
+       }
+
+       /**
+        * Return keys
+        * 
+        * @return {@link Collection} for key
+        * 
+        * @see java.util.Map#keySet()
+        */
+       public
+       Collection<K>
+       keySet() {
+               return map.keySet();
+       }
+
+       /**
+        * Return values for <code>key</code>
+        * 
+        * Return <code>null</code> if no values
+        *
+        * @param key key for values
+        * 
+        * @return key related values
+        */
+       public
+       Collection<V>
+       get(
+               final K key
+       )
+       {
+               return map.get( key );
+       }
+
+       /**
+        * Replace a set of key-values
+        * 
+        * @param key key for key-valeus
+        * @param values values for key-values
+        * 
+        * @return old values for <code>key</code>
+        */
+       public
+       Collection<V>
+       set(
+               final K key,
+               final Collection<V> values
+       )
+       {
+               return map.put( key, values );
+       }
+
+       /**
+        * Remove a set of key-values
+        * 
+        * @param key key for key-values
+        * 
+        * @return values to be removed
+        */
+       public
+       Collection<V>
+       remove(
+               final K key
+       )
+       {
+               return map.remove( key );
+       }
+
+       /**
+        * Remove key-value pair from a set and return values after change
+        *
+        * Return <code>null</code> if no values
+        * 
+        * @param key key for key-value
+        * @param value value for key-value
+        * 
+        * @return values after change
+        */
+       public
+       Collection<V>
+       remove(
+               final K key,
+               final V value
+       )
+       {
+               final Collection<V> values = map.get( key );
+               values.remove( value );
+
+               if ( values.isEmpty() )
+               {
+                       map.remove( key );
+                       return null;
+               }
+
+               return values;
+       }
+
+       /**
+        * Remove all sets
+        */
+       public
+       void
+       clear()
+       {
+               map.clear();
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public
+       String
+       toString()
+       {
+               final StringBuilder buffer = new StringBuilder();
+
+               buffer.append( "CollectionMap[" );
+
+               boolean bInit = false;
+
+               for ( final K key : map.keySet() )
+               {
+                       if ( bInit )
+                       {
+                               buffer.append( ", " );
+                       }
+                       bInit = true;
+                       buffer.append( key );
+                       buffer.append( '=' );
+                       buffer.append( map.get( key ) ); 
+               }
+
+               buffer.append( "]" );
+
+               return buffer.toString();
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/CollectionUtil.java b/org.tizen.common/src/org/tizen/common/util/CollectionUtil.java
new file mode 100644 (file)
index 0000000..2d5a024
--- /dev/null
@@ -0,0 +1,1890 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.tizen.common.util.StringUtil.EMPTY_STRING;
+import static org.tizen.common.util.StringUtil.NULL_STRING;
+
+import java.lang.reflect.InvocationTargetException;
+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.common.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>
+        * run <code>runner</code> iterateing element of <code>collection</code>.
+        * 
+        * use without null-check for <code>collection</code>
+        * 
+        * delegate error handling to <code>runner</code>
+        * </p>
+        * 
+        * <code>
+        * 
+        * CollectionUtil.iterate(
+        *      new ArrayList<String>( Arrays.asList( "hello", "Hello", "World", null, "Test" ) ),
+        *      new IteratingRunner<String>() {
+        *              public void run( String arg ) {
+        *                      ...
+        *              }
+        *      }
+        * );
+        * 
+        * </code>
+        * 
+        * @param <T> type of element in <code>collection</code>
+        * @param collection {@link Collection} containing element
+        * @param runner {@link Runnable} to execute
+        * 
+        * @throws InvocationTargetException when <code>runner</code>'s {@link Runnable#run()} throws exception 
+        * 
+        * @see {@link #iterate(Collection, IteratingRunner, boolean)}
+        * @see FilterIterator
+        */
+       public static <T>
+       void
+       iterate(
+               final Collection<? extends T> collection,
+               final IteratingRunner<T> runner
+       )
+       throws InvocationTargetException
+       {
+               iterate( collection, runner, false );
+       }
+       
+       /**
+        * <p>
+        * run <code>runner</code> iterateing element of <code>collection</code>.
+        * 
+        * use without null-check for <code>collection</code>
+        * 
+        * delegate error handling to <code>runner</code>
+        * 
+        * </p>
+        * <code>
+        * 
+        * CollectionUtil.iterate(
+        *      new ArrayList<String>( Arrays.asList( "hello", "Hello", "World", null, "Test" ) ),
+        *      new IteratingRunner<String>() {
+        *              public void run( String arg ) {
+        *                      ...
+        *              }
+        *      },
+        *      true
+        * );
+        * 
+        * </code>
+        * 
+        * @param <T> type of element in <code>collection</code>
+        * @param collection {@link Collection} containing element
+        * @param runner {@link Runnable} to execute
+        * @param bForceProcess flag to iterate continuously when exception occurs
+        * 
+        * @throws InvocationTargetException when <code>runner</code>'s {@link Runnable#run()} throws exception 
+        * 
+        * @see FilterIterator
+        */
+       public static <T>
+       void
+       iterate(
+               final Collection<? extends T> collection,
+               final IteratingRunner<T> runner,
+               final boolean bForceProcess
+       )
+       throws InvocationTargetException
+       {
+               if ( null == runner )
+               {
+                       return ;
+               }
+               if ( isEmpty( collection ) )
+               {
+                       return ;
+               }
+               
+               for ( final T arg : collection )
+               {
+                       if ( null == arg && !bForceProcess )
+                       {
+                               continue ;
+                       }
+                       try
+                       {
+                               runner.run( arg );
+                       } catch ( Throwable e )
+                       {
+                               if ( !bForceProcess )
+                               {
+                                       throw new InvocationTargetException( e );
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * <p>
+        * fiter <code>collection</code> to <code>result</code> using <code>runner</code>
+        * 
+        * determined if stop or keep going using <code>bForceProcess</code> in case of exception.
+        * </p>
+        * 
+        * @param <T> type of element in <code>collection</code>
+        * @param collection {@link Collection} to filter
+        * @param results collection to save result
+        * @param runner object to determine if filter
+        * @param bForceProcess flag to keep going when exception occurs
+        * 
+        * @throws InvocationTargetException when <code>runner</code>'s {@link Runnable#run()} throws exception 
+        */
+       public static <T>
+       void
+       filter(
+               final Collection<? extends T> collection,
+               final Collection<T> results,
+               final IteratingAcceptor<T> runner,
+               final boolean bForceProcess
+       ) throws InvocationTargetException
+       {
+               if ( null == results )
+               {
+                       return ;
+               }
+               if ( isEmpty( collection ) )
+               {
+                       return ;
+               }
+               
+               for ( final T arg : collection )
+               {
+                       if ( null == arg && !bForceProcess )
+                       {
+                               continue ;
+                       }
+                       try
+                       {
+                               if ( runner.accept( arg ) )
+                               {
+                                       results.add( arg );
+                               }
+                       } catch ( Throwable e )
+                       {
+                               if ( !bForceProcess )
+                               {
+                                       throw new InvocationTargetException( e );
+                               }
+                       }
+
+               }
+       }
+       
+       /**
+        * <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
+               )
+               {
+                       if ( null == enumeration )
+                       {       // Fast fail
+                               throw new NullPointerException();
+                       }
+                       
+                       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
+       )
+       {
+               if ( null == collection )
+               {
+                       throw new NullPointerException();
+               }
+
+               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 instanceof Object[] )
+               {
+                       return toString( ( Object[] ) obj );
+               }
+               else if ( obj instanceof boolean[] )
+               {
+                       return toString( ( boolean[] ) obj );
+               }
+               else if ( obj instanceof byte[] )
+               {
+                       return toString( ( byte[] )obj );
+               }
+               else if ( obj instanceof char[] )
+               {
+                       return toString( ( char[] ) obj );
+               }
+               else if ( obj instanceof double[] )
+               {
+                       return toString( ( double[] ) obj );
+               }
+               else if ( obj instanceof float[] )
+               {
+                       return toString( (float[] ) obj );
+               }
+               else if ( obj instanceof int[] )
+               {
+                       return toString( (int[] ) obj );
+               }
+               else if ( obj instanceof long[] )
+               {
+                       return toString( ( long[] ) obj );
+               }
+               else if ( obj instanceof short[] )
+               {
+                       return toString( ( short[] )obj );
+               }
+               return ObjectUtil.nvl( obj.toString(), EMPTY_STRING );
+       }
+       
+       /**
+        * Converts <code>array</code> boolean[] to String.
+        * 
+        * @param array boolean[] to convert
+        * 
+        * @return converted String
+        */
+       public static
+       String
+       toString(
+               final boolean[] array
+       )
+       {
+               if ( null == array )
+               {
+                       return NULL_STRING;
+               }
+               
+               final int length = array.length;
+               
+               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[i] ) );
+               }
+               buffer.append( ARRAY_END );
+               return buffer.toString();
+       }
+
+       /**
+        * Converts <code>array</code> byte[] to String.
+        * 
+        * @param array byte[] to convert
+        * 
+        * @return converted String
+        */
+       public static
+       String
+       toString(
+               final byte[] array
+       )
+       {
+               if ( null == array )
+               {
+                       return NULL_STRING;
+               }
+
+               final int length = array.length;
+
+               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[i] ) );
+               }
+               buffer.append( ARRAY_END );
+               return buffer.toString();
+       }
+
+       /**
+        * Converts <code>array</code> char[] to String.
+        * 
+        * @param array char[] to convert
+        * 
+        * @return converted String
+        */
+       public static
+       String
+       toString(
+               final char[] array
+       )
+       {
+               if ( null == array )
+               {
+                       return NULL_STRING;
+               }
+               
+               final int length = array.length;
+               
+               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[i] ) );
+               }
+               buffer.append( ARRAY_END );
+               return buffer.toString();
+       }
+       
+
+       /**
+        * Converts <code>array</code> short[] to String.
+        * 
+        * @param array short[] to convert
+        * 
+        * @return converted String
+        */
+       public static
+       String
+       toString(
+               final short[] array
+       )
+       {
+               if ( null == array ) 
+               {
+                       return NULL_STRING; 
+               }
+
+               final int length = array.length;
+               
+               if ( 0 == length ) 
+               {
+                       return EMPTY_ARRAY; 
+               }
+
+               final StringBuilder buffer = new StringBuilder();
+               for( int i=0 ; i<length ; ++i )
+               {
+                       if ( 0 == i )
+                       {
+                               buffer.append( ARRAY_START );
+                       }
+                       else
+                       {
+                               buffer.append( ARRAY_ELEMENT_SEPARATOR );
+                       }
+
+                       buffer.append( array[i] );
+               }
+               buffer.append( ARRAY_END );
+               return buffer.toString();
+       }
+       
+       /**
+        * Converts <code>array</code> int[] to String.
+        * 
+        * @param array int[] to String
+        * 
+        * @return converted String
+        */
+       public static
+       String
+       toString(
+               final int[] array
+       )
+       {
+               if ( null == array )
+               {
+                       return NULL_STRING; 
+               }
+
+               final int length = array.length;
+               
+               if ( 0 == length )
+               {
+                       return EMPTY_ARRAY; 
+               }
+
+               final StringBuilder buffer = new StringBuilder();
+               for( int i=0 ; i<length ; ++i )
+               {
+                       if ( 0 == i )
+                       {
+                               buffer.append( ARRAY_START );
+                       }
+                       else
+                       {
+                               buffer.append( ARRAY_ELEMENT_SEPARATOR );
+                       }
+
+                       buffer.append( array[i] );
+               }
+               buffer.append( ARRAY_END );
+               return buffer.toString();
+       }
+
+       /**
+        * Converts <code>array</code> long[] to String.
+        * 
+        * @param array long[] to convert
+        * 
+        * @return converted String
+        */
+       public static
+       String
+       toString(
+               final long[] array
+       )
+       {
+               if ( null == array ) 
+               {
+                       return NULL_STRING; 
+               }
+
+               int length = array.length;
+               
+               if ( 0 == length ) 
+               {
+                       return EMPTY_ARRAY; 
+               }
+
+               final StringBuilder buffer = new StringBuilder();
+               for( int i=0 ; i<length ; ++i)
+               {
+                       if ( 0 == i )
+                       {
+                               buffer.append( ARRAY_START );
+                       }
+                       else
+                       {
+                               buffer.append( ARRAY_ELEMENT_SEPARATOR );
+                       }
+
+                       buffer.append( array[i] );
+               }
+               buffer.append( ARRAY_END );
+               return buffer.toString();
+       }
+
+       /**
+        * Converts <code>array</code> double[] to String.
+        * 
+        * @param array double[] to convert 
+        * 
+        * @return converted String
+        */
+       public static
+       String
+       toString(
+               final double[] array
+       )
+       {
+               if ( null == array )
+               { 
+                       return NULL_STRING;
+               }
+               
+               int length= array.length;
+               
+               if ( 0 == length )
+               {
+                       return EMPTY_ARRAY; 
+               }
+
+               StringBuilder buffer = new StringBuilder();
+               for( int i=0 ; i<length ; ++i )
+               {
+                       if ( 0 == i )
+                       {
+                               buffer.append( ARRAY_START);
+                       }
+                       else
+                       {
+                               buffer.append( ARRAY_ELEMENT_SEPARATOR);
+                       }
+
+                       buffer.append( array[i] );
+               }
+               buffer.append( ARRAY_END );
+               return buffer.toString();
+       }
+
+       /**
+        * Converts <code>array</code> float[] to String.
+        * 
+        * @param array float[] to convert
+        * 
+        * @return converted String
+        */
+       public static
+       String
+       toString(
+               final float[] array
+       )
+       {
+               if ( null == array )
+               {
+                       return NULL_STRING; 
+               }
+
+               int length = array.length;
+               
+               if ( 0 == length )
+               {
+                       return EMPTY_ARRAY; 
+               }
+
+               final StringBuilder buffer = new StringBuilder();
+               for( int i=0 ; i < length ; ++i )
+               {
+                       if ( 0 == i )
+                       {
+                               buffer.append( ARRAY_START );
+                       }
+                       else
+                       {
+                               buffer.append( ARRAY_ELEMENT_SEPARATOR );
+                       }
+
+                       buffer.append( array[i] );
+               }
+               buffer.append( ARRAY_END );
+               return buffer.toString();
+       }
+
+       /**
+        * Converts <code>array</code> Object[] to String.
+        * 
+        * @param array Object[] to convert
+        * 
+        * @return converted String
+        */
+       public static <T>
+       String
+       toString(
+               final T[] array
+       )
+       {
+               if ( null == array )
+               {
+                       return NULL_STRING;
+               }
+               
+               final int length = array.length;
+               
+               if ( 0 == length )
+               {
+                       return EMPTY_ARRAY; 
+               }
+
+               final StringBuilder buffer= new StringBuilder();
+               
+               buffer.append( ARRAY_START);
+               buffer.append( concatenate( array, ARRAY_ELEMENT_SEPARATOR ) );
+               buffer.append( ARRAY_END );
+               return buffer.toString();
+       }
+
+       /**
+        * 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;
+       }
+}
index c0cb6f5..8e7ddb6 100644 (file)
@@ -75,8 +75,10 @@ public class ControlFileConfig {
        
        public boolean store(){
                File folder = new File(this.path).getParentFile();
-               if(folder==null||!folder.exists())
+               if( !folder.exists() )
+               {
                        folder.mkdirs();
+               }
                
                this.isExist = PropertyUtil.storeProperties(path, props);
                return this.isExist;
index 3335ba1..8961df7 100644 (file)
@@ -26,7 +26,6 @@
 package org.tizen.common.util;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.MessageBox;
 import org.eclipse.swt.widgets.Shell;
 
@@ -48,7 +47,7 @@ public abstract class DialogUtil {
     }
 
     public static void openMessageDialog(final Shell shell, final String title, final String message) {
-        Display.getDefault().syncExec(new Runnable() {
+       SWTUtil.syncExec(new Runnable() {
             public void run() {
                 MessageBox dialog = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION);
                 dialog.setText(title);
@@ -60,7 +59,7 @@ public abstract class DialogUtil {
 
     public static void openProxyDialog(final String text, String message) {
         final String msg = message;
-        Display.getDefault().syncExec(new Runnable() {
+        SWTUtil.syncExec(new Runnable() {
             public void run() {
                 MessageBox dialog = new MessageBox(new Shell(), SWT.ERROR | SWT.ICON_INFORMATION);
                 dialog.setText(text);
@@ -83,7 +82,7 @@ public abstract class DialogUtil {
     }
 
     public static void openErrorDialog(final Shell shell, final String title, final String message) {
-        Display.getDefault().syncExec(new Runnable() {
+       SWTUtil.syncExec(new Runnable() {
             public void run() {
                 MessageBox dialog = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
                 dialog.setText(title);
@@ -106,7 +105,7 @@ public abstract class DialogUtil {
     public static int openQuestionDialog(String message) {
         synchronized (lockQuestion) {
             final String msg = message;
-            Display.getDefault().syncExec(new Runnable() {
+            SWTUtil.syncExec(new Runnable() {
                 public void run() {
                     MessageBox dialog = new MessageBox(new Shell(), SWT.YES | SWT.NO | SWT.ICON_QUESTION);
                     dialog.setMessage(msg);
diff --git a/org.tizen.common/src/org/tizen/common/util/EFSUtil.java b/org.tizen.common/src/org/tizen/common/util/EFSUtil.java
new file mode 100755 (executable)
index 0000000..47d33ea
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Jihoon Song <jihoon80.song@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.common.util;
+
+import java.net.URI;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.filesystem.IFileSystem;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils;
+import org.eclipse.ui.internal.ide.dialogs.IFileStoreFilter;
+import org.tizen.common.Surrogate;
+import org.tizen.common.core.application.Messages;
+
+/**
+ * EFSUtil.
+ * 
+ * Helper related to Eclipse File System
+ * 
+ * @author Jihoon Song{@literal <jihoon80.song@samsung.com>} (S-Core)
+ */
+public class EFSUtil {
+    
+    public enum DialogChoicer {
+        YesToAll,
+        NoToAll,
+        Yes,
+        No,
+        Cancel;
+        
+        /**
+         * Get DialogChoicer's all value
+         * 
+         * @return String array with DialogChoicer's values
+         */
+        public static String[] toStringArray() {
+            DialogChoicer[] choicers = DialogChoicer.values();
+            String[] values = new String[choicers.length];
+            for (DialogChoicer choicer : choicers) {
+                values[choicer.ordinal()] = choicer.name();
+            }
+            return values;
+        }
+        
+        public static DialogChoicer valueFromOrdinal(int ordinal) {
+            for (DialogChoicer choicer : values()) {
+                if (choicer.ordinal() == ordinal) {
+                    return choicer;
+                }
+            }
+            return DialogChoicer.Cancel;
+        }
+    }
+    
+    private static Surrogate<IFileSystem> fileSystemSurrogate = new Surrogate<IFileSystem>() {
+        @Override
+        public IFileSystem getAdapter() {
+            return EFS.getLocalFileSystem();
+        }
+    };
+    
+    private static final String defaultTask = ""; //$NON-NLS-1$
+    private static final int defaultTicks = 100; // TODO : will add automatically calculate method
+    
+    private static final IFileStoreFilter defaultFilter = new IFileStoreFilter() {
+        @Override
+        public boolean accept(IFileStore store) {
+            return true;
+        }
+    };
+    
+    
+    // Constructor
+    private EFSUtil() {}
+    
+    public static void setFileSystemSurrogate(Surrogate<IFileSystem> surrogate) {
+        EFSUtil.fileSystemSurrogate = surrogate;
+    }
+    
+    /**
+     * Get IFileSystem based on Surrogate<IFileSystem> for this class
+     * 
+     * @return IFileStoreFilter
+     */
+    protected static IFileSystem getFileSystem() {
+        return fileSystemSurrogate.getAdapter();
+    }
+    
+    /**
+     * Get a default IFileStoreFilter that always returns true
+     * 
+     * @return IFileStoreFilter 
+     */
+    public static IFileStoreFilter getDefaultFileStoreFilter() {
+        return defaultFilter;
+    }
+    
+    /**
+     * Detect whether resource exist.
+     * 
+     * @param fileURI
+     */
+    public static boolean isExistResource(URI fileURI) {
+        IFileStore fileStore = getFileSystem().getStore(fileURI);
+        return isExistResource(fileStore);
+    }
+    
+    /**
+     * Detect whether resource exist.
+     * 
+     * @param fileStore
+     */
+    public static boolean isExistResource(IFileStore fileStore) {
+        return (fileStore != null) ? fileStore.fetchInfo().exists() : false;
+    }
+    
+    /**
+     * Detect whether resource exist. if exist this, open dialog
+     * 
+     * @param parentShell dialog's parent shell
+     * @param title dialog title
+     * @param msg dialog message
+     * @param previousChoice previous DialogChoicer value
+     * @param fileStore
+     * @return in case of previousChoice is Yes or No, return user choice status. any else return previous status
+     */
+    public static DialogChoicer isExistResourceWithDialog(Shell parentShell,
+            String title, String msg, DialogChoicer previousChoice, IFileStore fileStore) {
+        
+        Assert.notNull(parentShell);
+        Assert.notNull(msg);
+        Assert.notNull(previousChoice);
+        Assert.notNull(fileStore);
+        
+        switch (previousChoice) {
+        case Yes :
+        case No :
+            break;
+        case YesToAll :
+        case NoToAll :
+        case Cancel :
+        default :
+            return previousChoice;
+        }
+        
+        if (isExistResource( fileStore )) {
+            MessageDialog msgDialog = new MessageDialog(parentShell,
+                    title, null, msg, MessageDialog.NONE, DialogChoicer.toStringArray(),
+                    DialogChoicer.Cancel.ordinal());
+            
+            int msgResult = msgDialog.open();
+            
+            return DialogChoicer.valueFromOrdinal(msgResult);
+        }
+        
+        return DialogChoicer.Yes;
+    }
+    
+    /**
+     * Copy file or directory using Eclipse File System
+     * 
+     * @param source the source URI of the copy. If null, NullPointerException occur.
+     * @param destination the destination URI of the copy. If null, NullPointerException occur.
+     * @param options bit-wise or of option flag constants ({@link EFS#OVERWRITE} or {@link EFS#SHALLOW}).
+     * @param monitor a progress monitor, or <code>null</code> if progress reporting and cancellation are not desired
+     * 
+     * @author Jihoon Song {@literal <jihoon80.song@samsung.com>} (S-Core)
+     */
+    public static void copy(URI source, URI destination, int options,
+            IProgressMonitor monitor) throws CoreException {
+        Assert.notNull(source);
+        Assert.notNull(destination);
+        
+        monitor = ObjectUtil.nvl(monitor, new NullProgressMonitor());
+        
+        try {
+            monitor.beginTask(defaultTask, defaultTicks);
+            
+            getFileSystem().getStore(source).copy(getFileSystem().getStore( destination ), options, monitor);
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    /**
+     * Copy file or directory using EFS with IFileStoreFilter.
+     * If file already exist, open selectable message dialog.
+     * If the user selected Cancel, OperationCanceledException occur
+     * 
+     * @param source the source URI of the copy. If null, NullPointerException occur.
+     * @param destination the destination URI of the copy. If null, NullPointerException occur.
+     * @param fileFilter the child file filter in source, if <code>null</code>, the default file filter is used
+     * @param monitor a progress monitor, or <code>null</code> if progress reporting and cancellation are not desired
+     * @throws CoreException
+     */
+    public static DialogChoicer copyWithFilter(URI source, URI destination, IFileStoreFilter fileFilter,
+            IProgressMonitor monitor) throws CoreException {
+        return copyWithFilter(source, destination, fileFilter, DialogChoicer.Yes, monitor);
+    }
+    
+    /**
+     * Copy file or directory using EFS with IFileStoreFilter.
+     * If file already exist, open selectable message dialog.
+     * If the user selected Cancel, OperationCanceledException occur
+     * 
+     * @param source the source URI of the copy. If null, NullPointerException occur.
+     * @param destination the destination URI of the copy. If null, NullPointerException occur.
+     * @param fileFilter the child file filter in source, if <code>null</code>, the default file filter is used
+     * @param previousChoice apply user configuration. if YesToAll or NoToAll, don't ask your choice.
+     * @param monitor a progress monitor, or <code>null</code> if progress reporting and cancellation are not desired
+     * @throws CoreException
+     */
+    public static DialogChoicer copyWithFilter(URI source, URI destination, IFileStoreFilter fileFilter,
+            DialogChoicer previousChoice, IProgressMonitor monitor) throws CoreException {
+        Assert.notNull(source);
+        Assert.notNull(destination);
+        
+        monitor = ObjectUtil.nvl(monitor, new NullProgressMonitor());
+        
+        try {
+            monitor.beginTask(defaultTask, defaultTicks);
+            
+            // fileFilter must be not null, because IDEResourceInfoUtils don't check null.
+            if (fileFilter == null) {
+                fileFilter = getDefaultFileStoreFilter();
+            }
+                
+            return internalCopyWithFilter(getFileSystem().getStore( source ),
+                    getFileSystem().getStore( destination ),
+                    fileFilter, previousChoice, monitor);
+        } finally {
+            monitor.done();
+        }
+    }
+    
+    private static DialogChoicer internalCopyWithFilter(IFileStore source, IFileStore destination,
+            IFileStoreFilter fileFilter, DialogChoicer previousChoice, IProgressMonitor monitor)
+            throws CoreException {
+        Assert.notNull(source);
+        Assert.notNull(destination);
+        
+        previousChoice = isExistResourceWithDialog(
+                ViewUtil.getWorkbenchWindow().getShell(), Messages.FileExistDialogTitle,
+                Messages.bind( Messages.FileExistMsg, destination.getName() ),
+                previousChoice, destination);
+        
+        switch (previousChoice) {
+        case YesToAll :
+        case Yes :
+            source.copy(destination, EFS.OVERWRITE | EFS.SHALLOW, monitor);
+            break;
+        case Cancel :
+            throw new OperationCanceledException();
+        case NoToAll :
+        case No :
+            break;
+        default:
+            break;
+        }
+        monitor.worked(1);
+        
+        // traverse child resources
+        if (source.fetchInfo().isDirectory()) {
+            IFileStore[] childStores = IDEResourceInfoUtils.listFileStores(source, fileFilter, null);
+            for (IFileStore childStore : childStores) {
+                previousChoice = internalCopyWithFilter(childStore,
+                        destination.getChild( childStore.getName() ),
+                        fileFilter, previousChoice, monitor);
+            }
+        }
+        
+        return previousChoice;
+    }
+}
index eca82e5..59befe2 100644 (file)
@@ -1,29 +1,31 @@
 /*
-*  Common
-*
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
-*
-* Contact: 
-* 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
-*
-*/
+ *  Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: 
+ * 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.common.util;
 
+import static org.tizen.common.util.IOUtil.tryClose;
+
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
@@ -36,49 +38,174 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.net.URI;
-
-import org.eclipse.core.filesystem.EFS;
-import org.eclipse.core.filesystem.IFileSystem;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
 
+import org.tizen.common.util.log.Logger;
 
 /**
  * @author Changhyun Lee {@literal <changhyun1.lee@samsung.com>} (S-Core)
  */
 public class FileUtil {
-    public static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
-
     private static final int BUFFER_SIZE = 8192;
 
     /**
+     * Create directory.
+     * @param dir
+     * @return If directory couldn't be created, return false. Otherwise, return true.
+     */
+    public static boolean createDirectory(File dir) {
+        return dir.mkdirs();
+    }
+
+    /**
+     * Create directory.
+     * @param fullPath
+     * @return If directory couldn't be created, return false. Otherwise, return true.
+     */
+    public static boolean createDirectory(String fullPath) {
+        return createDirectory(new File(fullPath));
+    }
+
+    /**
+     * Create directory.
+     * @param dirName
+     * @param destDir If destDir is not set(null), then use user's current directory.
+     * @return If directory couldn't be created, return false. Otherwise, return true.
+     */
+    public static boolean createDirectory(String dirName, String destDir) {
+        if (dirName == null)
+            throw new NullPointerException();
+
+        if (destDir == null)
+            destDir = System.getProperty("user.dir");
+
+        String fullPath = FilenameUtil.addTailingPath(destDir, dirName);
+
+        return createDirectory(new File(fullPath));
+    }
+
+    /**
+     * Create text file.
+     * 
+     * @param file
+     * @param text Input file's context.
+     * @param encoding If encoding is not set(null), then use system's default encoding.
+     * 
+     * @return If file create fail, return false. Otherwise, return true.
+     * 
+     * @throws IOException If creating file's directory does not exist, it throws IOException
+     */
+    public static boolean createTextFile(File file, String text, String encoding) throws IOException {
+        if (!file.createNewFile())
+            return false;
+
+        return writeTextFile(file, text, encoding);
+    }
+
+    /**
+     * Create text file.
+     * 
+     * @param fullPath
+     * @param text Input file's context.
+     * @param encoding If encoding is not set(null), then use system's default encoding.
+     * 
+     * @return If file create fail, return false. Otherwise, return true.
+     * 
+     * @throws IOException If creating file's directory does not exist, it throws IOException
+     */
+    public static boolean createTextFile(String fullPath, String text, String encoding) throws IOException {
+        return createTextFile(new File(fullPath), text, encoding);
+    }
+
+    /**
+     * Create text file.
+     * 
+     * @param fileName
+     * @param text Input file's context.
+     * @param destDir If destDir is not set(null), then use user's current directory.
+     * @param encoding If encoding is not set(null), then use system's default encoding.
+     * 
+     * @return If file create fail, return false. Otherwise, return true.
+     * 
+     * @throws IOException If creating file's directory does not exist, it throws IOException
+     */
+    public static boolean createTextFile(String fileName, String text, String destDir, String encoding) throws IOException {
+        if (fileName == null)
+            throw new NullPointerException();
+
+        if (destDir == null)
+            destDir = System.getProperty("user.dir");
+
+        String fullPath = FilenameUtil.addTailingPath(destDir, fileName);
+
+        return createTextFile(fullPath, text, encoding);
+    }
+
+    /**
      * write text into given file
+     *
+     * @param file
+     * @param text Input context
+     * @param encoding If encoding is not set(null), then use system's default encoding.
+     *
+     * @return If file write success, return true.
+     *
+     * @throws IOException If don't write file, it throws IOException
      */
-    public static void writeTextFile(File file, String text, String encoding) throws IOException {
-        BufferedWriter out = null;
-    
+    public static boolean writeTextFile(File file, String text, String encoding) throws IOException {
         if (encoding == null) { // if encoding is not set then use default encoding
             encoding = System.getProperty("file.encoding");
         }
-    
+
+        File parent = file.getParentFile();
+        if (!parent.exists()) {
+            if (!parent.mkdirs()) {
+                throw new IOException("File write error. Cannot create directory - " + parent.getAbsolutePath());
+            }
+        }
+
+        BufferedWriter out = null;
         try {
             out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), encoding), BUFFER_SIZE);
             out.write(text.toCharArray(), 0, text.length());
             out.flush();
+        } catch (IOException e) {
+            throw e;
         } finally {
             if (out != null) {
                 out.close();
             }
         }
+
+        return true;
     }
 
     /**
-     *  read text from given file 
+     *  Read text from given file.
+     *
+     * @param file
+     * @param encoding
+     *
+     * @return content from file
+     *
+     * @throws IOException
      */
     public static String readTextFile(File file, String encoding) throws IOException {
+        return readTextStream(new FileInputStream(file), encoding);
+    }
+
+    /**
+     *  Read text from given inputStream.
+     *
+     * @param input
+     * @param encoding
+     *
+     * @return content from input
+     *
+     * @throws IOException
+     *
+     */
+    public static String readTextStream(InputStream input, String encoding) throws IOException {
         StringBuilder text = new StringBuilder();
-        char[] buffer = new char[BUFFER_SIZE];
         BufferedReader in = null;
 
         if (encoding == null) { // if encoding is not set then use default encoding
@@ -86,15 +213,10 @@ public class FileUtil {
         }
 
         try {
-            in = new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding), BUFFER_SIZE);
-            int nRead = 0;
-            while ((nRead = in.read(buffer, 0, buffer.length)) > 0) {
-                text.append(buffer, 0, nRead);
-            }
+            in = new BufferedReader(new InputStreamReader(input, encoding), BUFFER_SIZE);
+            IOUtil.redirect( in, text );
         } finally {
-            if (in != null) {
-                in.close();
-            }    
+            IOUtil.tryClose( in );
         }
 
         return text.toString();
@@ -126,7 +248,7 @@ public class FileUtil {
         }
 
         int k = fullName.lastIndexOf(".");
-        
+
         return (k != -1) ? fullName.substring(0, k) : fullName;
     }
 
@@ -157,21 +279,6 @@ public class FileUtil {
     }
 
     /**
-     * copy file or directory using Eclipse File System
-     * 
-     * @param source The source URI of the copy.
-     * @param destination The destination URI of the copy.
-     * @param options bit-wise or of option flag constants ({@link EFS#OVERWRITE} or {@link EFS#SHALLOW}).
-     * @param monitor a progress monitor, or <code>null</code> if progress reporting and cancellation are not desired
-     * 
-     * @author Jihoon Song {@literal <jihoon80.song@samsung.com>} (S-Core)
-     */
-    public static void copyUsingEFS(URI source, URI destination, int options, IProgressMonitor monitor) throws CoreException {
-        IFileSystem fileSystem = EFS.getLocalFileSystem();
-        fileSystem.getStore(source).copy(fileSystem.getStore(destination), options, monitor);
-    }
-
-    /**
      * redirect input stream to output stream
      */
     public static void redirectStream(InputStream is, OutputStream os) throws IOException {
@@ -218,7 +325,8 @@ public class FileUtil {
         }
 
         // makes sure it is not the same file
-        if (fromFile.getCanonicalPath().equals(toFile.getCanonicalPath())) {
+        if ( FilenameUtil.equals( fromFile, toFile ) )
+        {
             throw new IOException("Unable to write file " + fromFile + " on itself.");
         }
 
@@ -229,14 +337,80 @@ public class FileUtil {
             in = new BufferedInputStream(new FileInputStream(fromFile), BUFFER_SIZE);
             out = new BufferedOutputStream(new FileOutputStream(to, append), BUFFER_SIZE);
 
-            byte[] bytes = new byte[BUFFER_SIZE];
-            int nRead = 0;
-            while ((nRead = in.read(bytes, 0, bytes.length)) > 0) {
-                out.write(bytes, 0, nRead);
-            }
+            IOUtil.redirect( in, out );
         } finally {
-            if (in != null) in.close();
-            if (out != null) out.close();
+            tryClose( in, out );
         }
     }
+
+    /**
+     * Copy all the files in the source directory to the destination directory.
+     * If destination directory does not exist, it is created.
+     * If destination file already exists , it tries to overwrite it.
+     *
+     * @param from source directory path
+     * @param to destination directory path
+     * @throws IOException
+     */
+    public static void copyRecursively(String from, String to) throws IOException {
+        File fromDir = new File(from);
+        File toDir = new File(to);
+        if (fromDir.exists() == false) {
+            Logger.error("Directory " + fromDir.getCanonicalPath() + " does not exist.");
+            return;
+        }
+        checkDirectory(fromDir, toDir);
+        copyRecursivelyWithoutDirChecking(fromDir, toDir);
+    }
+
+    private static void checkDirectory(File fromDir, File toDir) throws IOException {
+        if (toDir.exists() == false) {
+            toDir.mkdirs();
+        } else if(toDir.isFile() == true) {
+            throw new IOException("destination directory " + toDir.toString() + " is a file.");
+        }
+
+        if (fromDir.exists() == false) {
+            throw new IOException("source directory " + fromDir.toString() + " does not exist.");
+        }
+
+        if (fromDir.isFile() == true) {
+            throw new IOException("source directory " + fromDir.toString() + " is a file.");
+        }
+    }
+
+    private static void copyRecursivelyWithoutDirChecking(File fromDir, File toDir) throws IOException {
+        for(File fromFile: fromDir.listFiles()) {
+            String newDestPath = toDir.getCanonicalPath();
+            if(newDestPath.endsWith(File.separator)) {
+                newDestPath = newDestPath + fromFile.getName();
+            } else {
+                newDestPath = newDestPath + File.separator + fromFile.getName();
+            }
+
+            File toFile = new File(newDestPath);
+            if(fromFile.isDirectory()) {
+                copyRecursivelyWithoutDirChecking(fromFile, toFile);
+            } else if(fromFile.isFile()){
+                copyTo(fromFile.getCanonicalPath(), newDestPath);
+            }
+        }
+    }
+
+    /**
+     * Compares the two files "file1" and "file2".
+     */
+    public static boolean equals(File file1, File file2) throws IOException {
+        if ( file1 == null || file2 == null) {
+            return false;
+        }
+        String strFile1 = file1.getCanonicalPath();
+        String strFile2 = file2.getCanonicalPath();
+
+        if ( strFile1 == null || strFile2 == null ) {
+            return false;
+        }
+
+        return strFile1.equals(strFile2);
+    }
 }
diff --git a/org.tizen.common/src/org/tizen/common/util/FilenameUtil.java b/org.tizen.common/src/org/tizen/common/util/FilenameUtil.java
new file mode 100755 (executable)
index 0000000..ef4d648
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.tizen.common.util.ArrayUtil.size;
+import static org.tizen.common.util.StringUtil.trimLeadingCharacter;
+import static org.tizen.common.util.StringUtil.trimTrailingCharacter;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
+/**
+ * FilenameUtil.
+ * 
+ * Helper related to file name
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class FilenameUtil
+{
+       public static final char SEPARATOR_DIRECTORY = '/';
+       public static final int IS_VALID_NAME = 0;
+       public static final int HAS_INVALID_CHARACTER = 1;
+       public static final int HAS_NO_NAME = 2;
+       public static final int IS_NULL = 3;
+       
+       /**
+        * Separate path to directory name fragements
+        * 
+        * @param path file path
+        * 
+        * @return canonical path's fragements
+        */
+       public static
+       String[]
+       getCanonicalFragments( final String path )
+       {
+               final String safe = path.replace( File.separatorChar, SEPARATOR_DIRECTORY);
+               final ArrayList<String> ret = new ArrayList<String>();
+               for ( final String fragment : safe.split( "" + SEPARATOR_DIRECTORY ) )
+               {
+                       if ( StringUtil.isEmpty( fragment ) )
+                       {
+                               continue;
+                       }
+                       
+                       ret.add( fragment );
+               }
+               return ret.toArray( new String[0] );
+       }
+
+       public static
+       String
+       getTailingPath(
+               final String path,
+               final int start
+       )
+       {
+               final String[] fragments = getCanonicalFragments( path );
+               
+               final StringBuilder buffer = new StringBuilder();
+               
+               for ( int i = Math.max( 0, size( fragments ) - start ), n = size( fragments ) ; i < n ; ++i )
+               {
+                       buffer.append( fragments[i] );
+                       if ( i < size( fragments ) - 1 )
+                       {
+                               buffer.append( SEPARATOR_DIRECTORY );
+                       }
+               }
+               
+               return buffer.toString();
+       }
+
+       public static
+       String
+       removeTailingPath(
+               final String path,
+               final int numberOfPath
+       )
+       {
+               final String[] fragments = getCanonicalFragments( path );
+               
+               final StringBuilder buffer = new StringBuilder();
+               
+               for ( int i = 0, n = Math.max( 0, size( fragments ) - numberOfPath ) ; i < n ; ++i )
+               {
+                       buffer.append( SEPARATOR_DIRECTORY );
+                       buffer.append( fragments[i] );
+               }
+               
+               return buffer.toString();
+       }
+       
+       public static
+       String
+       addTailingPath(
+               final String path,
+               final String pathToAdd
+       )
+       {
+               // TODO Verify canonical form
+               return trimTrailingCharacter( path, SEPARATOR_DIRECTORY ) + SEPARATOR_DIRECTORY + trimLeadingCharacter( pathToAdd, SEPARATOR_DIRECTORY );
+       }
+       
+       public static
+       boolean
+       isAncestor( final String root, final String filePath )
+       {
+               final String[] rootFragments = FilenameUtil.getCanonicalFragments( root );
+               final String[] fileFragments = FilenameUtil.getCanonicalFragments( filePath );
+               
+               if ( fileFragments.length < rootFragments.length )
+               {
+                       return false;
+               }
+               
+               for ( int i = 0, n = rootFragments.length ; i < n ; ++i )
+               {
+                       if ( !ObjectUtil.equals( rootFragments[i], fileFragments[i] ) )
+                       {
+                               return false;
+                       }
+               }
+               
+
+               return true;
+       }
+       
+       public static
+       String
+       getRelativePath(
+               final String root,
+               final String filePath
+       )
+       {
+               final String[] rootFragments = FilenameUtil.getCanonicalFragments( root );
+               final String[] fileFragments = FilenameUtil.getCanonicalFragments( filePath );
+               
+               Assert.isTrue(
+                       rootFragments.length < fileFragments.length,
+                       "root must be ancestor[" + root + "] of path[" + filePath + "]"
+               );
+               
+               for ( int i = 0, n = rootFragments.length ; i < n ; ++i )
+               {
+                       Assert.isTrue( ObjectUtil.equals( rootFragments[i], fileFragments[i] ) );
+               }
+               
+               
+               
+               final StringBuilder buffer = new StringBuilder();
+               
+               for ( int i = rootFragments.length, n = fileFragments.length ; i < n ; ++i )
+               {
+                       if ( rootFragments.length < i )
+                       {
+                               buffer.append( SEPARATOR_DIRECTORY );
+                       }
+                       buffer.append( fileFragments[i] );
+               }
+               
+               return buffer.toString();
+       }
+
+       
+       /**
+        * Create canonical form for file path
+        * 
+        * @param file {@link File} with file path
+        * 
+        * @return canonical path
+        * 
+        * @throws IOException If file's path is illegal
+        */
+       public static
+       String
+       getCanonicalPath(
+               final File file
+       )
+       throws IOException
+       {
+               final String osCanonicalPath = file.getCanonicalPath();
+               
+               return getCanonicalForm( osCanonicalPath );
+               
+       }
+       
+       /**
+        * Convert path to canonical form
+        * 
+        * @param path file path
+        * 
+        * @return canonical path
+        */
+       public static
+       String
+       getCanonicalForm(
+               final String path
+       )
+       {
+               if ( File.separatorChar == SEPARATOR_DIRECTORY )
+               {
+                       return path;
+               }
+               
+               return path.replace( File.separatorChar, SEPARATOR_DIRECTORY );
+       }
+       
+       public static String getFilename( final String path )
+       {
+               return getTailingPath( path, 1 );
+       }
+       
+    /**
+     * Returns an escaped name of the file name for linux.
+     * 
+     * \ " $ => \\ \" \$
+     * 
+     * @param fileName
+     */
+    public static String getEscapedName(String fileName)
+    {
+        Pattern sEscapePattern = Pattern.compile("([\\\\\"$])");
+        return sEscapePattern.matcher(fileName).replaceAll("\\\\$1");
+    }
+
+    /**
+     * Return validation check of filename
+     * 
+     * Windows does not allow \ / : * ? " <> | for file name
+     * 
+     * Linux does not allow / for file name
+     * 
+     * @param fileName file name to check
+     * 
+     * @param os os type from OSChecker
+     * 
+     * @return validation check result
+     */
+    public static int isVaildName(String fileName, int os)
+    {
+        int result = IS_VALID_NAME;
+        if(fileName == null)
+        {
+            result = IS_NULL;
+        }
+        
+        if(fileName.length() == 0)
+        {
+            result = HAS_NO_NAME;
+        }
+        else
+        {
+            Pattern invalidPattern;
+
+            switch(os)
+            {
+                case OSChecker.WINDOWS:
+                    invalidPattern = Pattern.compile("([\\\\/:*?\"<>|])");
+                    break;
+                case OSChecker.LINUX:
+                default:
+                    invalidPattern = Pattern.compile("([/])");
+            }
+
+            if(invalidPattern.matcher(fileName).find())
+            {
+                result = HAS_INVALID_CHARACTER;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Return validation check of filename for host os
+     * 
+     * @param fileName file name to check
+     * 
+     * @return validation check result
+     */
+    public static boolean isVaildName(String fileName)
+    {
+        return isVaildName(fileName, OSChecker.getOSID()) == IS_VALID_NAME ? true : false;
+    }
+
+    /**
+     * Return invalid filename characters
+     * 
+     * @param os os type from OSChecker
+     * 
+     * @return validation check result
+     */
+    public static String getInvalidCharacters(int os)
+    {
+        switch(os)
+        {
+            case OSChecker.WINDOWS:
+                return "\\\\/:*?\"<>|";
+            case OSChecker.LINUX:
+                return "/";
+            default:
+                return "/";
+        }
+    }
+
+    /**
+     * Return invalid filename characters for host os
+     * 
+     * @return validation check result
+     */
+    public static String getInvalidCharacters()
+    {
+        return getInvalidCharacters(OSChecker.getOSID());
+    }
+
+    public static String addDoubleQuote(String str)
+    {
+        return "\""+ str + "\"";
+    }
+
+       /**
+        * Extract file name without extension from full name
+        * 
+        * @param nameWithExt file name with extension
+        * 
+        * @return file name
+        */
+       public static String getName( final String nameWithExt )
+       {
+               if ( null == nameWithExt )
+               {
+                       throw new NullPointerException();
+               }
+               
+               final int index = nameWithExt.lastIndexOf( '.' );
+               
+               if ( index < 0 )
+               {
+                       return nameWithExt;
+               }
+               
+               return nameWithExt.substring( 0, index );
+       }
+       
+       /**
+        * Extract file extension from full name
+        * 
+        * @param nameWithExt file name with extension
+        * 
+        * @return file extension
+        */
+       public static String getExtension( final String nameWithExt )
+       {
+               if ( null == nameWithExt )
+               {
+                       throw new NullPointerException();
+               }
+               
+               final int index = nameWithExt.lastIndexOf( '.' );
+               
+               if ( index < 0 )
+               {
+                       return "";
+               }
+               
+               return nameWithExt.substring( index + 1 );
+       }
+       
+       /**
+        * Compare two file path with canonical
+        * 
+        * @param file1 file1 to compare
+        * @param file2 file2 to compare
+        * 
+        * @return <code>true</code> if <code>file1</code> and <code>file2</code> have equal path
+        */
+       public static boolean equals( final File file1, final File file2 )
+       {
+               try
+               {
+                       return ObjectUtil.equals(
+                               getCanonicalPath( file1 ),
+                               getCanonicalPath( file2 )
+                       );
+               } catch ( final IOException e )
+               {
+                       throw new IllegalArgumentException();
+               }
+       }
+       
+       
+       public static boolean equals( final String path1, final String path2 )
+       {
+               return ObjectUtil.equals( path1, path2 );
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/FilterIterator.java b/org.tizen.common/src/org/tizen/common/util/FilterIterator.java
new file mode 100644 (file)
index 0000000..1002235
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * FilterIterator.
+ *
+ * {@link Iterator} using filter method
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @param <E>
+ */
+public class 
+FilterIterator<E>
+implements Iterator<E>
+{
+       /**
+        * Unfiltered iterator
+        */
+       protected final Iterator<? extends E> impl;
+       
+       /**
+        * Acceptable element
+        */
+       protected E acceptableElement;
+       
+       /**
+        * Constructor with array instance of type E
+        * 
+        * @param array array to iterate
+        */
+       public
+       FilterIterator(
+               final E[] array
+       )
+       {
+               this( Arrays.asList( array ) );
+       }
+       
+       /**
+        * Constructor with collection containing E object
+        * 
+        * @param collection collection to iterate
+        */
+       public
+       FilterIterator(
+               final Collection<? extends E> collection
+       )
+       {
+               this.impl = ( null == collection )?null:collection.iterator();
+       }
+
+       /* (non-Javadoc)
+        * @see java.util.Iterator#hasNext()
+        */
+       @Override
+       public
+       boolean
+       hasNext()
+       {
+               if ( null == this.impl )
+               {
+                       return false;
+               }
+               
+               while ( this.impl.hasNext() )
+               {
+                       final E element = this.impl.next();
+                       if ( isAcceptable( element ) )
+                       {
+                               this.acceptableElement = element;
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /* (non-Javadoc)
+        * @see java.util.Iterator#next()
+        */
+       @Override
+       public
+       E
+       next()
+       {
+               if ( null == this.impl )
+               {
+                       throw new NoSuchElementException();
+               }
+               
+               return this.acceptableElement;
+       }
+
+       /* (non-Javadoc)
+        * @see java.util.Iterator#remove()
+        */
+       @Override
+       public
+       void
+       remove()
+       {
+               if ( null == this.impl )
+               {
+                       throw new NoSuchElementException();
+               }
+               this.impl.remove();
+       }
+       
+       /**
+        * Determine <code>element</code> is acceptable( not filtering )
+        * 
+        * @param element object to check
+        * 
+        * @return boolean value if <code>element is acceptable
+        */
+       protected
+       boolean
+       isAcceptable(
+               final E element
+       )
+       {
+               if ( null == element )
+               {
+                       return false;
+               }
+               
+               return true;
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/FreeMarkerUtil.java b/org.tizen.common/src/org/tizen/common/util/FreeMarkerUtil.java
new file mode 100644 (file)
index 0000000..b43d60f
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Jihoon Song <jihoon80.song@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.common.util;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+import freemarker.template.Configuration;
+import freemarker.template.DefaultObjectWrapper;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+/**
+ * FreeMarkerUtil.
+ * 
+ * Helper related to FreeMarker
+ * 
+ * @author Jihoon Song{@literal <jihoon80.song@samsung.com>} (S-Core)
+ */
+public class FreeMarkerUtil {
+    
+    private final static String DEFAULT_ENCODING = "8859_1";
+    
+    // Constructor
+    private FreeMarkerUtil() {}
+    
+    /**
+     * Get default initialized template configuration.
+     * 
+     * @return Configuration
+     */
+    public static Configuration getDefaultConfiguration() {
+        // initialize FreeMarker engine
+        Configuration cfg = new Configuration();
+        cfg.setEncoding(Locale.getDefault(), DEFAULT_ENCODING); //$NON-NLS-1$
+        cfg.setObjectWrapper(new DefaultObjectWrapper());
+        
+        return cfg;
+    }
+    
+    /**
+     * Get initialized template configuration.
+     * 
+     * @param activator be used for Plug-in based relative path. If this value is null, throws NullPointerException.
+     * @param relativeParentPath relative template's parent path in Plug-in Bundle.
+     * @return Configuration
+     * @throws URISyntaxException
+     * @throws IOException
+     */
+    public static Configuration getConfiguration(AbstractUIPlugin activator, String relativeParentPath)
+            throws URISyntaxException, IOException {
+        Assert.notNull(activator);
+        Assert.notNull(relativeParentPath);
+        
+        Configuration cfg = getDefaultConfiguration();
+        
+        // set template location in plug-in
+        URL templateFolderURL = activator.getBundle().getEntry(relativeParentPath);
+        if (templateFolderURL == null) {
+            throw new FileNotFoundException();
+        }
+        
+        URI templateFolderURI = FileLocator.toFileURL(templateFolderURL).toURI();
+        File templateFolder = new File(templateFolderURI);
+        
+        cfg.setDirectoryForTemplateLoading(templateFolder);
+        
+        return cfg;
+    }
+    
+    /**
+     * Generate document using freemarker template.
+     * 
+     * @param root template data model
+     * @param cfg template configuration instance
+     * @param templateFile template file
+     * @param destination output file name
+     * @throws IOException
+     * @throws TemplateException
+     */
+    public static void generateDocument(Map<String, Object> root, Configuration cfg, String templateFile, String destination)
+            throws IOException, TemplateException {
+        generateDocument(root, cfg, templateFile, new File( destination ));
+    }
+    
+    /**
+     * Generate document using freemarker template.
+     * 
+     * @param root template data model
+     * @param cfg template configuration instance
+     * @param templateFile template file
+     * @param destinationFile will be used for internal stream like FileOutputStream.
+     * @throws IOException
+     * @throws TemplateException
+     */
+    public static void generateDocument(Map<String, Object> root, Configuration cfg, String templateFile, File destinationFile)
+            throws IOException, TemplateException {
+        generateDocument(root, cfg, templateFile, new FileOutputStream( destinationFile ));
+    }
+    
+    /**
+     * Generate document using freemarker template.
+     * 
+     * @param root template data model
+     * @param cfg template configuration instance
+     * @param templateFile template file
+     * @param outputStream will be used for internal writer like BufferedWriter and OutputStreamWriter.
+     * @throws IOException
+     * @throws TemplateException
+     */
+    public static void generateDocument(Map<String, Object> root, Configuration cfg, String templateFile, OutputStream outputStream)
+            throws IOException, TemplateException {
+        generateDocument(root, cfg, templateFile, new BufferedWriter( new OutputStreamWriter( outputStream ) ));
+    }
+    
+    /**
+     * Generate document using freemarker template.
+     * 
+     * @param root template data model
+     * @param cfg template configuration instance
+     * @param templateFile template file
+     * @param writer output writer
+     * @throws IOException
+     * @throws TemplateException
+     */
+    public static void generateDocument(Map<String, Object> root, Configuration cfg, String templateFile, Writer writer)
+            throws IOException, TemplateException {
+        Assert.notNull(root);
+        Assert.notNull(cfg);
+        Assert.notNull(templateFile);
+        Assert.notNull(writer);
+        
+        Template template = cfg.getTemplate(templateFile);
+        
+        // generate document
+        try {
+            template.process(root, writer);
+            IOUtil.tryFlush(writer);
+        } finally {
+            IOUtil.tryClose(writer);
+        }
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/HelpBrowser.java b/org.tizen.common/src/org/tizen/common/util/HelpBrowser.java
new file mode 100644 (file)
index 0000000..58db9e3
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Ho Namkoong <ho.namkoong@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.common.util;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.browser.LocationListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.IWorkbenchHelpSystem;
+import org.tizen.common.CommonPlugin;
+
+public class HelpBrowser {
+    
+    private static final String HELP_PAGE_PREFIX = "help:/";
+    private static final String BACK_ICON = "icons/back.gif";
+    private static final String FORWARD_ICON = "icons/forward.gif";
+    
+    private Browser browser;
+
+    public Browser getBrowser() {
+        return browser;
+    }
+
+    public HelpBrowser(Composite parent, int style) {
+        this(parent, style, false);
+    }
+    
+    public HelpBrowser(Composite parent, int style, boolean hasToolbar) {
+        if(hasToolbar == true) {
+            generateToolBar(parent);
+        }
+        this.browser = new Browser(parent, style);
+        GridData gd = new GridData(GridData.FILL_BOTH);
+        this.browser.setLayoutData(gd);
+        enableHelpPage();
+    }
+
+    private void generateToolBar(Composite parent) {
+        ToolBar toolbar = new ToolBar(parent, SWT.None);
+        
+        ToolItem backButton = new ToolItem(toolbar, SWT.PUSH);
+        Image backIcon = ImageUtil.getImage(CommonPlugin.PLUGIN_ID, BACK_ICON);
+        backButton.setImage(backIcon);
+        
+        ToolItem forwardButton = new ToolItem(toolbar, SWT.PUSH);
+        Image forwardIcon = ImageUtil.getImage(CommonPlugin.PLUGIN_ID, FORWARD_ICON);
+        forwardButton.setImage(forwardIcon);
+        
+        forwardButton.addSelectionListener(new SelectionListener() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                browser.forward();
+            }
+
+            @Override
+            public void widgetDefaultSelected(SelectionEvent e) {
+            }
+        });
+        
+        backButton.addSelectionListener(new SelectionListener() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                browser.back();
+            }
+
+            @Override
+            public void widgetDefaultSelected(SelectionEvent e) {
+            }
+        });
+    }
+
+    private void enableHelpPage() {
+        this.getBrowser().addLocationListener(new LocationListener() {
+            @Override
+            public void changing(LocationEvent event) {
+                String url = event.location;
+                if(url.startsWith(HELP_PAGE_PREFIX)) {
+                    Browser browser = ((Browser)event.widget);
+                    String tempUrl = url.substring(HELP_PAGE_PREFIX.length(), url.length());
+                    IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();
+                    browser.setUrl(helpSystem.resolve(tempUrl, false).toString());
+                }
+            }
+            @Override
+            public void changed(LocationEvent event) {
+            }
+        });
+    }
+}
old mode 100644 (file)
new mode 100755 (executable)
index a2e1b68..012a60c
 */
 package org.tizen.common.util;
 
+import static org.tizen.common.util.IOUtil.tryClose;
+
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
-import java.io.IOException;
 import java.io.InputStreamReader;
-import java.net.InetAddress;
 import java.nio.channels.FileChannel;
 
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
-import org.tizen.common.console.ConsoleManager;
+import org.tizen.common.ui.view.console.ConsoleManager;
 
 public abstract class HostUtil{
-       
-//     public static final String USER = System.getenv("USER");
-//     public static final String USER_HOME = System.getenv("HOME");
-       public static final String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
-       public static final String FILE_SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$
-       
-       private static final String PROC_PATH = "/proc"; //$NON-NLS-1$
-       private static final String SHELL_COMMAND_LINUX= "/bin/sh"; //$NON-NLS-1$
-       private static final String SHELL_COMMAND_WINDOW= "cmd"; //$NON-NLS-1$
-       
-       public static boolean hasProcFile(String pid) {
-               if(pid==null||pid.equals("")) //$NON-NLS-1$
-                       return false;
+    
+    public static final String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
+    public static final String FILE_SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$
+    
+    private static final String SHELL_COMMAND_LINUX= "/bin/sh"; //$NON-NLS-1$
+    private static final String SHELL_COMMAND_WINDOW= "cmd"; //$NON-NLS-1$
+    
+    public static String getContents(String filePath) {
+        BufferedReader input = null;
+        StringBuilder contents = new StringBuilder();
+        String line = null;
+        
+        try {
+            input = new BufferedReader(new FileReader(filePath));
+            while((line=input.readLine())!=null){
+                contents.append(line);
+                contents.append(LINE_SEPARATOR);
+            }
+        }catch(Exception e) {
+//            e.printStackTrace();
+            return null;
+        }finally{
+            tryClose( input );
+        }
+        
+        return contents.toString().trim();
+    }
 
-               String pidFile = PROC_PATH+Path.SEPARATOR+pid;
-               return exists(pidFile);
-       }
-       public static boolean isMenuReady(String pid) {
-               if(pid==null||pid.equals("")) //$NON-NLS-1$
-                       return false;
+    public static boolean exists(String path) {
+        if( path == null || path.equals("") ) //$NON-NLS-1$
+            return false;
 
-               String pidFile = PROC_PATH+Path.SEPARATOR+pid;
-               return exists(pidFile);
-       }
+        File file = new File( path );
 
-       
-       public static String getContents(String filePath) {
-               BufferedReader input = null;
-               StringBuilder contents = new StringBuilder();
-               String line = null;
-               
-               try {
-                       input = new BufferedReader(new FileReader(filePath));
-                       while((line=input.readLine())!=null){
-                               contents.append(line);
-                               contents.append(LINE_SEPARATOR);
-                       }
-               }catch(Exception e) {
-//                     e.printStackTrace();
-                       return null;
-               }finally{
-                       if(input!=null)
-                               try {
-                                       input.close();
-                               } catch (IOException e) {
-                               }
-               }
-               
-               return contents.toString().trim();
-       }
-       
-       public static boolean isReachable(String ip) {
-               try {
-                       return InetAddress.getByName(ip).isReachable(100);
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-               return false;
-       }
+        return file.exists();
+    }
 
-       public static boolean exists(String path) {
-               if(path==null||path.equals("")) //$NON-NLS-1$
-                       return false;
-               
-               IPath ipath = new Path(path);
-               File file = ipath.toFile();
-                       
-               if(file!=null&&file.exists())
-                       return true;
-               else
-                       return false;
-       }
-       
-       public static boolean execute(String command){
-               Process proc = null;
-               Runtime runtime = Runtime.getRuntime();
-               
-               String[] fullCommand = getCommand(command);
-               
-               int i = 0;
-               try {
-                       proc= runtime.exec(fullCommand);
-                       i = proc.waitFor();
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       return false;
-               } finally{
-                       System.out.println("HostUtil execute - exit value : " + i);
-                       if(proc!=null)  
-                               proc.destroy();
-               }
-               
-               return i==0;
-       }
-       
-       public static boolean batchExecute(String command)      
-       {
-               String[] fullCommand = getCommand(command);
+    public static boolean execute(String command){
+        
+        if(command == null) {
+            return false;
+        }
+        Process proc = null;
+        Runtime runtime = Runtime.getRuntime();
+        
+        String[] fullCommand = getCommand(command);
+        
+        int i = 0;
+        try {
+            proc= runtime.exec(fullCommand);
+            i = proc.waitFor();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        } finally{
+            System.out.println("HostUtil execute - exit value : " + i);
+            if(proc!=null)    
+                proc.destroy();
+        }
+        
+        return i==0;
+    }
+    
+    public static boolean batchExecute(String command)    
+    {
+        if(command == null) {
+            return false;
+        }
+        String[] fullCommand = getCommand(command);
 
-               Runtime run = Runtime.getRuntime();
-                 Process p = null;
-                 
-                 try{
-                  p = run.exec(fullCommand);
-                  StreamGobbler gb1 = new StreamGobbler(p.getInputStream());
-                  StreamGobbler gb2 = new StreamGobbler(p.getErrorStream());
-                  gb1.start();
-                  gb2.start();
-                 }catch(Exception e){
-                         e.printStackTrace();
-                         return false;
-                 }finally{
-                 } 
-               return true;
-       }
+        Runtime run = Runtime.getRuntime();
+          Process p = null;
+          
+          int i = 0;
+          try{
+           p = run.exec(fullCommand);
+           i = p.waitFor();
+           StreamGobbler gb1 = new StreamGobbler(p.getInputStream());
+           StreamGobbler gb2 = new StreamGobbler(p.getErrorStream());
+           gb1.start();
+           gb2.start();
+          }catch(Exception e){
+              e.printStackTrace();
+              return false;
+          } 
+        return i == 0;
+    }
 
-       /**
-        * Don't need for emultor install registration.
-        * using java.lang.Runtime.exec(String[] cmdarray, String[] envp, File dir) 
-        * @param command  - array containing the command to call and its arguments.
-        * @param envp - array of strings, each element of which has environment variable settings in format name=value.
-        * @param dir - Emultor path.
-        * @return success true, failed false.
-        */
-       public static boolean batchExecute(String command, String[] envp, File dir)     
-       {
-               String[] fullCommand = getCommand(command);
+    /**
+     * Don't need for emultor install registration.
+     * using java.lang.Runtime.exec(String[] cmdarray, String[] envp, File dir) 
+     * @param command  - array containing the command to call and its arguments.
+     * @param envp - array of strings, each element of which has environment variable settings in format name=value.
+     * @param dir - Emultor path.
+     * @return success true, failed false.
+     */
+    public static boolean batchExecute(String command, String[] envp, File dir)    
+    {
+        String[] fullCommand = getCommand(command);
 
-               Runtime run = Runtime.getRuntime();
-                 Process p = null;
+        Runtime run = Runtime.getRuntime();
+          Process p = null;
 
-                 StreamGobbler gb1 = null;
-                 StreamGobbler gb2 = null;
-                 try{
-                  p = run.exec(fullCommand, envp, dir);
-                  gb1 = new StreamGobbler(p.getInputStream());
-                  gb2 = new StreamGobbler(p.getErrorStream());
-                  gb1.start();
-                  gb2.start();
-                 }catch(Exception e){
-                         e.printStackTrace();
-                         return false;
-                 }finally{
-                         System.out.println(gb1.getResult());
-                         System.out.println(gb2.getResult());
-                 
-               return true;
-       }
+          StreamGobbler gb1 = null;
+          StreamGobbler gb2 = null;
+          try{
+           p = run.exec(fullCommand, envp, dir);
+           gb1 = new StreamGobbler(p.getInputStream());
+           gb2 = new StreamGobbler(p.getErrorStream());
+           gb1.start();
+           gb2.start();
+          }catch(Exception e){
+              e.printStackTrace();
+              return false;
+          }finally{
+              System.out.println(gb1.getResult());
+              System.out.println(gb2.getResult());
+          } 
+        return true;
+    }
 
-       public static String returnExecute(String command, String workingDir) {
-               BufferedReader input = null;
-               StringBuilder contents = new StringBuilder();
-               String line = null;
-               
-               Process proc = null;
-               
-               String[] fullCommand = getCommand(command);
-               
-               try {
-                               ProcessBuilder pb = new ProcessBuilder();
-                               pb.command(fullCommand);
-                               if(workingDir != null) {
-                                       pb.directory(new File(workingDir));
-                               }
-                               proc = pb.start();
-                               input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
-                               while((line=input.readLine())!=null){
-                                       contents.append(line);
-                                       contents.append(LINE_SEPARATOR);
-                               }
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       return null;
-               } finally{
-                       if(proc!=null)  
-                               proc.destroy();
-                       if(input!=null)
-                               try {
-                                       input.close();
-                               } catch (IOException e) {
-                               }
-               }
-               
-               return contents.toString().trim();
-               
-       }
-       
-       /**
-        * Show output messages while executes the command on console view
-        * @param command - Command to execute.
-        * @param viewName - View name showing messages while executes the command.
-        */
-       public static void executeWithConsole(String command, String viewName) throws Exception {
-               BufferedReader input = null;
+    public static String returnExecute(String command, String workingDir) {
+        
+        if(command == null) {
+            return null;
+        }
+        BufferedReader input = null;
+        StringBuilder contents = new StringBuilder();
+        String line = null;
+        
+        Process proc = null;
+        
+        String[] fullCommand = getCommand(command);
+        
+        try {
+                ProcessBuilder pb = new ProcessBuilder();
+                pb.command(fullCommand);
+                if(workingDir != null) {
+                    pb.directory(new File(workingDir));
+                }
+                proc = pb.start();
+                input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+                while((line=input.readLine())!=null){
+                    contents.append(line);
+                    contents.append(LINE_SEPARATOR);
+                }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        } finally{
+            tryClose( input );
+            if(proc!=null)    
+            {
+                proc.destroy();
+            }
+        }
+        
+        return contents.toString().trim();
+        
+    }
+    
+    /**
+     * Show output messages while executes the command on console view
+     * @param command - Command to execute.
+     * @param viewName - View name showing messages while executes the command.
+     */
+    public static void executeWithConsole(String command, String viewName) throws Exception {
+        BufferedReader input = null;
 
-               String line = null;
-               
-               Process proc = null;
-               
-               String[] fullCommand = getCommand(command);
-               
-               ConsoleManager cm = new ConsoleManager( viewName, true );
-               cm.clear();
-               
-               try {
-                       ProcessBuilder pb = new ProcessBuilder();
-                       pb.redirectErrorStream(true);
-                       pb.command(fullCommand);
-                       proc = pb.start();
-                       input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
-                       while((line=input.readLine())!=null){
-                               cm.println(line);
-                       }
-                       proc.waitFor();
-                       // abnormal termination
-                       if (proc.exitValue() != 0)
-                               throw new Exception("Failed to execute command: " + command);
-               } finally {
-                       if(proc!=null)
-                               proc.destroy();
-                       if(input!=null)
-                               try {
-                                       input.close();
-                               } catch (IOException e) {
-                               }
-               }
-       }
-       
-       public static String returnExecute(String command){
-               
-               return returnExecute(command, null);
-       }
-       
-       public static String[] getCommand(String command){
-               
-               if(OSChecker.isWindows()){
-                       return new String[]{SHELL_COMMAND_WINDOW,"/c",command}; //$NON-NLS-1$
-               }else
-               {
-                       return new String[]{SHELL_COMMAND_LINUX,"-c",command}; //$NON-NLS-1$
-               }
-       }
-       
-       
-       public static boolean createFile(String path, String contents) {
-               BufferedWriter output = null;
-               try {
-                       File file = new File(path);
-                       
-                       File folder = file.getParentFile();
-                       if(folder!=null)
-                               folder.mkdirs();
-                       
-                       file.createNewFile();
-                       
-                       output = new BufferedWriter(new FileWriter(file));
-                       output.write(contents);
-                       return true;
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       return false;
-               }finally{
-                       if(output!=null)
-                               try {
-                                       output.close();
-                               } catch (IOException e) {
-                               }
-               }
-       }
-       
-       public static boolean removeFile(String path) {
-               File file = new File(path);
-               if (!file.exists())
-                       return false;
-               return file.delete();
-       }
-       
-       /**
-       * @deprecated Use {@link FileUtil#copyTo(String, String)} instead.
-       */
-       @Deprecated
-       public static boolean copyFile(String src, String des) throws Exception  {
-               boolean canExecute = false;
-               File srcFile=new File(src);
-               File desFile=null;
-               FileInputStream fis=null;
-               FileOutputStream fos=null;
-               FileChannel fcin=null;
-               FileChannel fcout=null;
-               
-               canExecute = srcFile.canExecute();
-               
-               desFile= new File(des);
-               File paths = new File(desFile.getAbsolutePath().substring(0, desFile.getAbsolutePath().lastIndexOf("/"))); //$NON-NLS-1$
-               if (!paths.exists()) {
-                       paths.mkdirs();
-               }
-               
-               try {
-                       fis= new FileInputStream(srcFile);
-                       fos= new FileOutputStream(desFile);
-                       fcin= fis.getChannel();
-                       fcout= fos.getChannel();
-               
-                       long size= fcin.size();
-                       fcin.transferTo(0, size, fcout);
-                       desFile.setExecutable(canExecute);
-               } catch (FileNotFoundException e) {
-                       e.printStackTrace();
-                       throw e;
-               } catch (IOException e) {
-                       e.printStackTrace();
-                       throw e;
-               }finally{
-                       try {
-                               fcout.close();
-                               fcin.close();
-                               fos.close();
-                               fis.close();
-                       } catch (IOException e) {
-                               e.printStackTrace();
-                               throw e;
-                       }
-               }
+        String line = null;
+        
+        Process proc = null;
+        
+        String[] fullCommand = getCommand(command);
+        
+        ConsoleManager cm = new ConsoleManager( viewName, true );
+        cm.clear();
+        
+        try {
+            ProcessBuilder pb = new ProcessBuilder();
+            pb.redirectErrorStream(true);
+            pb.command(fullCommand);
+            proc = pb.start();
+            input = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+            while((line=input.readLine())!=null){
+                cm.println(line);
+            }
+            proc.waitFor();
+            // abnormal termination
+            if (proc.exitValue() != 0)
+                throw new Exception("Failed to execute command: " + command);
+        } finally {
+            tryClose( input );
+            if(proc!=null)
+            {
+                proc.destroy();
+            }
+        }
+    }
+    
+    public static String returnExecute(String command){
+        
+        return returnExecute(command, null);
+    }
+    
+    public static String[] getCommand(String command){
+        
+        if(OSChecker.isWindows()){
+            return new String[]{SHELL_COMMAND_WINDOW,"/c",command}; //$NON-NLS-1$
+        }else
+        {
+            return new String[]{SHELL_COMMAND_LINUX,"-c",command}; //$NON-NLS-1$
+        }
+    }
+    
+    /**
+    * @deprecated Use {@link FileUtil#createFile(File)}, 
+    * {@link FileUtil#createFile(String)}, 
+    * {@link FileUtil#createFile(String, String)} 
+    * or 
+    * {@link FileUtil#createTextFile(File, String, String)}, 
+    * {@link FileUtil#createTextFile(String, String, String)}, 
+    * {@link FileUtil#createTextFile(String, String, String, String)} 
+    * and 
+    * {@link FileUtil#createDirectory(File)}, 
+    * {@link FileUtil#createDirectory(String)}, 
+    * {@link FileUtil#createDirectory(String, String)} 
+    * instead.
+    */
+    @Deprecated
+    public static boolean createFile(String path, String contents) {
+        BufferedWriter output = null;
+        try {
+            File file = new File(path);
+            
+            File folder = file.getParentFile();
+            if(folder!=null)
+                folder.mkdirs();
+            
+            file.createNewFile();
+            
+            output = new BufferedWriter(new FileWriter(file));
+            output.write(contents);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }finally{
+            tryClose( output );
+        }
+    }
+    
+    
+    /**
+    * @deprecated Use {@link FileUtil#copyTo(String, String)} instead.
+    */
+    @Deprecated
+    public static boolean copyFile(String src, String des) throws Exception  {
+        boolean canExecute = false;
+        File srcFile=new File(src);
+        File desFile=null;
+        FileInputStream fis=null;
+        FileOutputStream fos=null;
+        FileChannel fcin=null;
+        FileChannel fcout=null;
+        
+        canExecute = srcFile.canExecute();
+        
+        desFile= new File(des);
+        File paths = new File(desFile.getAbsolutePath().substring(0, desFile.getAbsolutePath().lastIndexOf("/"))); //$NON-NLS-1$
+        if (!paths.exists()) {
+            paths.mkdirs();
+        }
+        
+        try {
+            fis= new FileInputStream(srcFile);
+            fos= new FileOutputStream(desFile);
+            fcin= fis.getChannel();
+            fcout= fos.getChannel();
+        
+            long size= fcin.size();
+            fcin.transferTo(0, size, fcout);
+            desFile.setExecutable(canExecute);
+        }finally{
+            tryClose( fcout, fcin, fos, fis );
+        }
 
-               return true;
-       }
-       
-       public static boolean isLinux(){
-               return Platform.getOS().equals(Platform.OS_LINUX);
-       }
+        return true;
+    }
+    
 }
 
 
index 0dce620..9fbd2e0 100644 (file)
 */
 package org.tizen.common.util;
 
+import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
+import java.io.Flushable;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * IOUtil
  * @author Hyeongseok Heo {@literal<hyeongseok.heo@samsung.com>}
+ * BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
  * @since Dec 9, 2011
  */
 public class IOUtil {
 
-       public static void close(Closeable closable) {
-               if( null != closable) {
-                       try {
-                               closable.close();
-                       } catch (IOException e) {
-                               // TODO Auto-generated catch block
-                               e.printStackTrace();
+    private static final int BUFFER_SIZE = 8192;
+    
+    protected static final Logger logger = LoggerFactory.getLogger( IOUtil.class );
+
+       /**
+        * close closable objects.
+        * 
+        * @param closeables object to be able to close
+        */
+       public static void tryClose( final Object... closeables )
+       {
+               if ( null == closeables )
+               {
+                       return ;
+               }
+               
+               for ( Object obj : closeables )
+               {
+                       if ( null == obj )
+                       {
+                               continue;
+                       }
+                       try
+                       {
+                               if ( obj instanceof Closeable )
+                               {
+                                       ((Closeable) obj).close();
+                               }
+                               else if ( obj instanceof Socket )
+                               {
+                                       ((Socket) obj).close();
+                               }
+                               else if ( obj instanceof ServerSocket )
+                               {
+                                       ((ServerSocket) obj).close();
+                               }
+                       }
+                       catch ( final IOException e )
+                       {
+                       }
+               }
+       }
+       
+       /**
+        * flush <code>Flushable</code>s
+        * 
+        * @param flushables <code>Flushable</code>s to flush
+        */
+       public static void tryFlush( final Flushable... flushables )
+       {
+               if ( null == flushables )
+               {
+                       return ;
+               }
+               
+               for ( Flushable closeable : flushables )
+               {
+                       if ( null == closeable )
+                       {
+                               continue;
+                       }
+                       try
+                       {
+                               closeable.flush();
+                       }
+                       catch ( final IOException e )
+                       {
+                       }
+               }
+               
+       }
+       
+       /**
+        * Redirect from <code>in</code> to <code>out</code>
+        * 
+        * @param in {@link InputStream}
+        * @param out {@link OutputStream}
+        * 
+        * @throws IOException occur exception when handling <code>in</code> or <code>out</code>
+        */
+       public static
+       void
+       redirect(
+               final InputStream in,
+               final OutputStream out
+       )
+       throws IOException
+       {
+               final byte[] buffer = new byte[BUFFER_SIZE];
+               
+               int nRead = 0;
+               int totalBytes = 0;
+               while ( 0 < ( nRead = in.read( buffer ) ) )
+               {
+                       out.write( buffer, 0, nRead );
+                       totalBytes += nRead;
+               }
+               
+               logger.trace( "{} byte(s) wrote", totalBytes );
+               
+               tryFlush( out );
+       }
+
+       /**
+        * Redirect from <code>reader</code> to <code>writer</code>
+        * 
+        * @param reader {@link Reader}
+        * @param writer {@link Writer}
+        * 
+        * @throws IOException occur exception when handling <code>reader</code> or <code>writer</code>
+        */
+       public static
+       void
+       redirect(
+               final Reader reader,
+               final Writer writer
+       )
+       throws IOException
+       {
+               final char[] buffer = new char[BUFFER_SIZE];
+               
+               int nRead = 0;
+               while ( 0 < ( nRead = reader.read( buffer ) ) )
+               {
+                       writer.write( buffer, 0, nRead );
+               }
+               tryFlush( writer );
+       }
+
+       /**
+        * Redirect from <code>reader</code> to <code>writer</code>
+        * 
+        * @param reader {@link Reader}
+        * @param writer {@link StringBuffer}
+        * 
+        * @throws IOException occur exception when handling <code>reader</code> or <code>writer</code>
+        */
+       public static
+       void
+       redirect(
+               final Reader reader,
+               final StringBuffer writer
+       )
+       throws IOException
+       {
+               final char[] buffer = new char[BUFFER_SIZE];
+               
+               int nRead = 0;
+               while ( 0 < ( nRead = reader.read( buffer ) ) )
+               {
+                       writer.append( buffer, 0, nRead );
+               }
+       }
+
+       /**
+        * Redirect from <code>reader</code> to <code>writer</code>
+        * 
+        * @param reader {@link Reader}
+        * @param writer {@link StringBuilder}
+        * 
+        * @throws IOException occur exception when handling <code>reader</code> or <code>writer</code>
+        */
+       public static
+       void
+       redirect(
+               final Reader reader,
+               final StringBuilder writer
+       )
+       throws IOException
+       {
+               if ( null == reader )
+               {
+                       return ;
+               }
+               final char[] buffer = new char[BUFFER_SIZE];
+               
+               int nRead = 0;
+               while ( 0 < ( nRead = reader.read( buffer ) ) )
+               {
+                       writer.append( buffer, 0, nRead );
+               }
+       }
+       
+       
+       /**
+        * Get and return byte array from {@link InputStream}
+        * 
+        * @param in input stream to read byte array
+        * 
+        * @return stored byte array
+        * 
+        * @throws IOException If can't read byte from <code>in</code>
+        * 
+        * @link {@link #getBytes(InputStream, boolean)}
+        */
+       public static
+       byte[] getBytes(
+               final InputStream in
+       )
+       throws IOException
+       {
+               return getBytes( in, false );
+       }
+
+       /**
+        * Get and return byte array from {@link InputStream}
+        * 
+        * @param in input stream to read byte array
+        * @param bClose optional flag if close <code>in</code> after processing 
+        * 
+        * @return stored byte array
+        * 
+        * @throws IOException If can't read byte from <code>in</code>
+        * 
+        * @link {@link #redirect(InputStream, OutputStream)}
+        */
+       public static
+       byte[] getBytes(
+               final InputStream in,
+               final boolean bClose
+       ) throws IOException
+       {
+               final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+
+               try
+               {
+                       redirect( in, byteOut );
+                       
+                       if ( bClose )
+                       {
+                               tryClose( in );
                        }
+                       
+                       return byteOut.toByteArray();
                }
+               finally
+               {
+                       tryClose( byteOut );
+               }
+               
+       }
+       
+       /**
+        * <p>
+        * Get and return string from {@link Reader}
+        * 
+        * return empty string( "" ) if <code>reader</code> is <code>null</code>
+        * </p>
+        * 
+        * @param reader reader to read string
+        * @return string to be accquired
+        * 
+        * @throws IOException If can't read string from {@link Reader}
+        * 
+        * @see #getString(Reader, boolean)
+        */
+       public static
+       String getString(
+               final Reader reader
+       )
+       throws IOException
+       {
+               return getString( reader, false );
+               
        }
+       
+       /**
+        * <p>
+        * Get and return string from {@link Reader}
+        * 
+        * Return empty string( "" ) if <code>reader</code> is <code>null</code>
+        * </p>
+        * 
+        * @param reader reader to read string
+        * @param bClose optional flag if close <code>in</code> after processing 
+        * 
+        * @return string to be accquired
+        * 
+        * @throws IOException If can't read string from {@link Reader}
+        * 
+        * @see #redirect(Reader, StringBuilder)
+        */
+       public static
+       String
+       getString(
+               final Reader reader,
+               final boolean bClose
+       )
+       throws IOException
+       {
+               final StringBuilder writer = new StringBuilder();
+               try {
+                       redirect( reader, writer );
+                       
+                       if ( bClose )
+                       {
+                               tryClose( reader );
+                       }
+                       
+                       return writer.toString();
+               }
+               finally
+               {
+                       tryClose( writer );
+               }
+               
+       }
+
+       /**
+        * <p>
+        * Get and return string from {@link InputStream}
+        * 
+        * Return empty string ( "" ) if <code>in</code> is <code>null</code>
+        * 
+        * @param in {@link InputStream} to read
+        * 
+        * @return string to be accquired
+        * 
+        * @throws IOException If can't read anything from {@link InputStream}
+        * 
+        * @see #getString(Reader)
+        */
+       public static
+       String
+       getString(
+               final InputStream in
+       )
+       throws IOException
+       {
+               return getString( new InputStreamReader( in ) );
+       }
+       
+
 }
@@ -31,19 +31,73 @@ import org.eclipse.core.runtime.Plugin;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.ImageData;
+import org.osgi.framework.Bundle;
+import org.tizen.common.SurrogateWithArgument;
 
 
-public class ImageUtils {
+public class ImageUtil {
+       public static class PlatformSurrogate {
+           public Bundle getBundle(String pluginID) {
+               return Platform.getBundle(pluginID);
+           }
+       }
+       
+       public static class PluginSurrogate {
+           public Bundle getBundle(Plugin plugin) {
+               return plugin.getBundle();
+           }
+       }
+
+    public static final String[] supportedImageExtension = {
+            "*.gif;*.png;*.jpeg;*.jpg;*.tiff;*.tif;*.ico;*.bmp;*.rle",  // all supported format in SWT //$NON-NLS-1$
+            "*.gif",  // Graphics Interchange Format, including animated GIFs //$NON-NLS-1$
+            "*.png",  // Portable Network Graphics //$NON-NLS-1$
+            "*.jpeg;*.jpg",  // Joint Photographic Experts Group //$NON-NLS-1$
+            "*.tiff;*.tif",  // Tagged Image File Format //$NON-NLS-1$
+            "*.ico",  // Widows Icon //$NON-NLS-1$
+            "*.bmp",  // Windows Bitmap //$NON-NLS-1$
+            "*.rle"   // Windows Bitmap with run-length encoding //$NON-NLS-1$
+    };
+       
+       /**
+        * load image descriptor from <code>bundle</code> with <code>filePath</code>
+        * 
+        * @param bundle {@link Bundle}
+        * @param filePath image file path
+        * 
+        * @return loaded {@link ImageDescriptor}
+        */
+       protected static
+       ImageDescriptor
+       getImageDescriptor(
+               final Bundle bundle,
+               final String filePath
+       )
+       {
+               final URL url = bundle.getEntry( filePath );
+               return ImageDescriptor.createFromURL( url );
+       }
+       
+       protected static SurrogateWithArgument<Bundle, String> platformSurrogate = new SurrogateWithArgument<Bundle, String>() {
+               public Bundle getAdapter( final String pluginId )
+               {
+                       return Platform.getBundle( pluginId );
+               }
+       };
+       protected static SurrogateWithArgument<Bundle, Plugin> pluginSurrogate = new SurrogateWithArgument<Bundle, Plugin>() {
+               public Bundle getAdapter(Plugin plugin) {
+                       return plugin.getBundle();
+               }
+       };
+       
        // get ImageDescriptor from Plugin ID (ID -> ImageDescriptor)
        public static ImageDescriptor getImageDescriptor(String pluginID, String filePath) {
-               URL url = Platform.getBundle(pluginID).getEntry(filePath);
-               return ImageDescriptor.createFromURL(url);
+               return getImageDescriptor( platformSurrogate.getAdapter(pluginID), filePath );
        }
 
        // get ImageDescriptor from Activator Plugin (Activator -> ImageDescriptor)
        public static ImageDescriptor getImageDescriptor(Plugin plugin, String filePath) {
-               URL url = plugin.getBundle().getEntry(filePath); // $NON-NLS-1$
-               return ImageDescriptor.createFromURL(url);
+               return getImageDescriptor( pluginSurrogate.getAdapter(plugin), filePath );
        }
 
        // get Image from ImageDescriptor (ImageDescriptor -> Image)
@@ -79,4 +133,4 @@ public class ImageUtils {
                ImageDescriptor descriptor = getImageDescriptor(pluginID, filePath);
                return getImageData(descriptor);
        }
-}
\ No newline at end of file
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/IteratingAcceptor.java b/org.tizen.common/src/org/tizen/common/util/IteratingAcceptor.java
new file mode 100644 (file)
index 0000000..bb8c3d1
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import java.util.Collection;
+
+/**
+ * IteratingAcceptor.
+ * 
+ * Filter logic containing iterface for {@link Collection} or array
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @param <T> arguement type
+ */
+public interface IteratingAcceptor<T>
+{
+       /**
+        * Check that <code>arg</code> is filtered or passed
+        * 
+        * @param arg collection element
+        * 
+        * @return <code>true</code> if <code>arg</code> is element to pass
+        */
+       boolean accept( T arg );
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/IteratingAdapter.java b/org.tizen.common/src/org/tizen/common/util/IteratingAdapter.java
new file mode 100644 (file)
index 0000000..6c29b90
--- /dev/null
@@ -0,0 +1,7 @@
+package org.tizen.common.util;
+
+import java.util.Iterator;
+
+public interface IteratingAdapter<T> {
+       public Iterator<T> adapt( T obj );
+}
@@ -1,42 +1,47 @@
-/*\r
-*  Common\r
-*\r
-* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
-*\r
-* Contact: \r
-* Kangho Kim <kh5325.kim@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
-\r
-package org.tizen.common.model;\r
-\r
-import java.util.Collection;\r
-\r
-public interface ITreeModel\r
-{\r
-       public void add(ITreeVO datas);\r
-       public void add(Collection<ITreeVO> datas);\r
-       public void remove(ITreeVO datas);\r
-       public void remove(Collection<ITreeVO> datas);\r
-       public ITreeVO[] getDatas();\r
-       public void load(String fileName);\r
-       public void save(String fileName);\r
-       public void clear();\r
-       public int size();\r
-       public String getSourceName();\r
-}\r
+/*
+*  Common
+*
+* 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.common.util;
+
+import java.util.Collection;
+
+/**
+ * IteratingRunner.
+ * 
+ * Runner with argument for iteration of {@link Collection} or array
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @param <T> arguement type
+ */
+public interface IteratingRunner<T>
+{
+       /**
+        * Run with collection element <code>arg</code>
+        * 
+        * @param arg collection element
+        */
+       public void run( T arg );
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/IteratingUtil.java b/org.tizen.common/src/org/tizen/common/util/IteratingUtil.java
new file mode 100644 (file)
index 0000000..c013370
--- /dev/null
@@ -0,0 +1,27 @@
+package org.tizen.common.util;
+
+import java.util.Iterator;
+
+public class IteratingUtil {
+       public static <T> void iterate( T obj, IteratingAdapter<T> adapter, IteratingRunner<T> runner )
+       {
+               if ( null == obj )
+               {
+                       return ;
+               }
+               
+               Iterator<T> iter = adapter.adapt( obj );
+               if ( null == iter )
+               {
+                       return ;
+               }
+               while ( iter.hasNext() )
+               {
+                       T child = iter.next();
+                       runner.run( child );
+                       iterate( child, adapter, runner );
+               }
+               
+       }
+
+}
index 68c3337..da15c12 100644 (file)
@@ -38,45 +38,52 @@ import java.net.ServerSocket;
  *  <li> added getAvailableLocalPort method.
  *  </ul> 
  */
-public class LocalPortChecker {
-    public static boolean isPortAvailable(int port) {
-        if ((port < 0) && (port > 65535))
-            return false;
+public class LocalPortChecker
+{
+       
+       public static boolean isPortInRange( final int port )
+       {
+               return ( 0 <= port ) && ( port < 65536 );
+               
+       }
+    public static boolean isPortAvailable( final int port )
+    {
+        if ( !isPortInRange( port ) )
+        {
+               return false;
+        }
         
         ServerSocket socket = null;
-        try {
-            socket = new ServerSocket(port);
+        try
+        {
+            socket = new ServerSocket( port );
             return true;
-        } catch (IOException e) {
-            return false;
-        } finally {
-            if (socket != null) {
-                try {
-                    socket.close();
-                } catch (IOException e) {
-                    // do nothing
-                }
-            }
-        }
-    }
-
-    public static int getAvailableLocalPort(int inc,int portBase) {
-       int port = portBase;
-        if (isPortAvailable(port)) {
-            return port;
         }
-
-        if ( (port+inc) > 65535) {
-            return -1;
+        catch ( final IOException e )
+        {
+            return false;
         }
-
-        while ((port < 65535) && !isPortAvailable(port)) {
-            port += inc;
+        finally
+        {
+               IOUtil.tryClose( socket );
         }
-
-        if (isPortAvailable(port))
-            return port;
-        else 
-            return -1;
+    }
+    
+    public static int
+    getAvailableLocalPort(
+       final int inc,
+       final int portBase
+    )
+    {
+       for ( int port = portBase ; true ; port += inc )
+       {
+               if ( !isPortInRange( port) )
+               {
+                       return -1;
+               }
+               if ( isPortAvailable( port ) ) {
+                       return port;
+               }
+       }
     }
 }
diff --git a/org.tizen.common/src/org/tizen/common/util/MapUtil.java b/org.tizen.common/src/org/tizen/common/util/MapUtil.java
new file mode 100644 (file)
index 0000000..f721875
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.tizen.common.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
+       )
+       {
+               if ( null == map )
+               {
+                       throw new NullPointerException();
+               }
+               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();
+       }
+
+}
index 3e8d5a8..ede8c87 100644 (file)
@@ -25,7 +25,7 @@
 package org.tizen.common.util;
 
 import org.eclipse.swt.graphics.Image;
-import org.tizen.common.cache.ImageCache;
+import org.tizen.common.util.cache.ImageCache;
 
 
 public enum NotificationType {
index 0474253..3944a19 100644 (file)
@@ -41,14 +41,13 @@ import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.PlatformUI;
-import org.tizen.common.cache.ColorCache;
-import org.tizen.common.cache.FontCache;
+import org.tizen.common.util.cache.ColorCache;
+import org.tizen.common.util.cache.FontCache;
 
 
 public class NotifierDialog {
@@ -133,7 +132,7 @@ public class NotifierDialog {
                     // get the size of the drawing area
                     Rectangle rect = _shell.getClientArea();
                     // create a new image with that size
-                    Image newImage = new Image(Display.getDefault(), Math.max(1, rect.width), rect.height);
+                    Image newImage = new Image(SWTUtil.getDisplay(), Math.max(1, rect.width), rect.height);
                     // create a GC object we can use to draw with
                     GC gc = new GC(newImage);
 
@@ -315,14 +314,14 @@ public class NotifierDialog {
                     }
 
                     _shell.setAlpha(cur);
-                    Display.getDefault().timerExec(FADE_TIMER, this);
+                    SWTUtil.getDisplay().timerExec(FADE_TIMER, this);
                 } catch (Exception err) {
                     err.printStackTrace();
                 }
             }
 
         };
-        Display.getDefault().timerExec(FADE_TIMER, run);
+        SWTUtil.getDisplay().timerExec(FADE_TIMER, run);
     }
 
     private static void startTimer(final Shell _shell) {
@@ -340,7 +339,7 @@ public class NotifierDialog {
             }
 
         };
-        Display.getDefault().timerExec(DISPLAY_TIME, run);
+        SWTUtil.getDisplay().timerExec(DISPLAY_TIME, run);
 
     }
 
@@ -367,7 +366,7 @@ public class NotifierDialog {
 
                     _shell.setAlpha(cur);
 
-                    Display.getDefault().timerExec(FADE_TIMER, this);
+                    SWTUtil.getDisplay().timerExec(FADE_TIMER, this);
 
                 } catch (Exception err) {
                     err.printStackTrace();
@@ -375,7 +374,7 @@ public class NotifierDialog {
             }
 
         };
-        Display.getDefault().timerExec(FADE_TIMER, run);
+        SWTUtil.getDisplay().timerExec(FADE_TIMER, run);
 
     }
 }
index 3331a46..9890ab0 100644 (file)
@@ -26,6 +26,7 @@ package org.tizen.common.util;
 
 /**
  * @author Changhyun Lee {@literal <changhyun1.lee@samsung.com>} (S-Core)
+ * @author Gyeongseok Seo {@literal <gyeongseok.seo@samsung.com>} (S-Core)
  *  <ul>
  *  <li> initial creation
  *  <li> thanks to Yoon Kyung Koo  
@@ -35,12 +36,14 @@ public class OSChecker {
     //
     // OS ID constants
     //
-    public final static int WINDOWS = 0x0001;
-    public final static int MAC = 0x0002;
-    public final static int LINUX = 0x0004;
-    public final static int UNIX = 0x0008;
-    public final static int AIX = 0x0010;
-    public final static int SOLARIS = 0x0020;
+    public final static int WINDOWS = 0x0100;
+    public final static int WINDOWSXP = 0x0101;
+    public final static int WINDOWS7 = 0x0102;
+    public final static int MAC = 0x0200;
+    public final static int LINUX = 0x0400;
+    public final static int UNIX = 0x0800;
+    public final static int AIX = 0x1000;
+    public final static int SOLARIS = 0x2000;
 
     //
     // Vendor constants
@@ -71,6 +74,11 @@ public class OSChecker {
 
         if (osName.indexOf("WINDOWS") >= 0) {
             osID |= OSChecker.WINDOWS;
+            if ( ObjectUtil.equals(osName, "WINDOWS XP") ) {
+                osID |= OSChecker.WINDOWSXP;
+            } else if ( ObjectUtil.equals(osName, "WINDOWS 7") ) {
+                osID |= OSChecker.WINDOWS7;
+            }
         } else if (osName.indexOf("MAC") >= 0) {
             osID |= OSChecker.MAC;
         } else if (osName.indexOf("LINUX") >= 0) {
@@ -108,6 +116,13 @@ public class OSChecker {
         return ((osID & OSChecker.WINDOWS) > 0);
     }
 
+    public static boolean isWindowsXP() {
+        return (osID == OSChecker.WINDOWSXP);
+    }
+    public static boolean isWindows7() {
+        return (osID == OSChecker.WINDOWS7);
+    }
+
     public static boolean isMAC() {
         return ((osID & OSChecker.MAC) > 0);
     }
@@ -157,4 +172,14 @@ public class OSChecker {
         return (vendorID == 0);
     }
 
+    /* querying arch */
+    public static boolean is64bit() {
+        boolean is64bit = false;
+        if ( OSChecker.isWindows() ) {
+            is64bit = (System.getenv("ProgramFiles(x86)") != null);
+        } else {
+            is64bit = (System.getProperty("os.arch").indexOf("64") != -1);
+        }
+        return is64bit;
+    }
 }
diff --git a/org.tizen.common/src/org/tizen/common/util/ObjectUtil.java b/org.tizen.common/src/org/tizen/common/util/ObjectUtil.java
new file mode 100644 (file)
index 0000000..3c0f2f8
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.tizen.common.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
+     */
+       @SuppressWarnings({
+                       "unchecked", "rawtypes"
+       })
+       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 );
+               }
+               else if ( obj1 instanceof Collection && obj2 instanceof Collection )
+               {
+                       return CollectionUtil.equals( (Collection) obj1, (Collection) obj2 );
+               }
+               else if ( obj1 instanceof Object[] && obj2 instanceof Object[] )
+               {
+                       return CollectionUtil.equals( (Object[]) obj1, (Object[]) 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 );
+               return buffer.toString();
+       }
+
+       /**
+        * Convert <code>i</code> to hexadecimal with <code>j</code> length
+        * 
+        * @param i decimal to convert
+        * @param j hexadecimal's length
+        * 
+        * @return converted hexadecimal
+        */
+       public static
+       String
+       hexFormat(
+               final int i,
+               final int j
+       )
+       {
+               final String s = Integer.toHexString( i );
+               return padHex( s, j );
+       }
+
+
+       /**
+        * Create GUID with 32 bytes
+        * 
+        * GUID is used for system( programe ) not human
+        * 
+        * Structure
+        * +-----------------+--------------+----------------------+------------------+
+        * | Current Time(8) | Server IP(8) | Object Hash Value(8) | Random Number(8) |
+        * +-----------------+--------------+----------------------+------------------+
+        * 
+        * @param obj object to hash
+        * @return create guid
+        */
+       public static final
+       String
+       generateGUID(
+               final Object obj
+       )
+       {
+               final StringBuilder guid = new StringBuilder( 32 );
+
+               // time
+               long timeNow = System.currentTimeMillis();
+               int timeLow = (int) timeNow& 0xFFFFFFFF;
+               guid.append( hexFormat( timeLow, 8 ) );
+
+               // server IP
+               if ( null == hexServerIP )
+               {
+                       InetAddress localInetAddress = null;
+                       try
+                       {
+                               // get the inet address
+                               localInetAddress = InetAddress.getLocalHost();
+                       }
+                       catch( final UnknownHostException uhe )
+                       {
+                               try
+                               {
+                                       localInetAddress = InetAddress.getByName( "localhost" );
+                               }
+                               catch ( final UnknownHostException e )
+                               {
+                                       e.printStackTrace();
+                                       return null;
+                               }
+                       }
+
+                       byte serverIP[] = localInetAddress.getAddress();
+
+                       hexServerIP = hexFormat( getInt( serverIP ), 8 );
+               }
+               guid.append( hexServerIP );
+
+               // object hash
+               guid.append( hexFormat( System.identityHashCode( obj ), 8 ) );
+
+               // random number
+               int node= -1;
+               synchronized( SEEDER )
+               {
+                       node = SEEDER.nextInt();
+               }
+               guid.append( hexFormat( node, 8 ) );
+               return guid.toString();
+       }
+
+       /* Serialize / Deserialize */
+       /**
+        * Serialize object
+        * 
+        * @param obj object to serialize
+        * 
+        * @return serialized byte array
+        * 
+        * @throws IOException If serialization is fail
+        * 
+        * @see ObjectOutputStream#writeObject( Object )
+        */
+       public static
+       byte[]
+       serialize(
+               final Object obj
+       )
+       throws IOException
+       {
+               final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+               final ObjectOutputStream objOut = new ObjectOutputStream( byteOut );
+               objOut.writeObject( obj );
+               return byteOut.toByteArray();
+       }
+
+       /**
+        * Deserialize byte array
+        * 
+        * @param bytes bytes to deserialize
+        * 
+        * @return Deserialized object
+        * 
+        * @throws IOException If deserialization is fail
+        * 
+        * @throws ClassNotFoundException If No class
+        * 
+        * @see ObjectInputStream#readObject()
+        */
+       public static
+       Object
+       deserialize(
+               final byte[] bytes
+       )
+       throws IOException, ClassNotFoundException
+       {
+               Assert.notNull( bytes, "bytes must not be null" );
+               final ByteArrayInputStream byteIn = new ByteArrayInputStream( bytes );
+               final ObjectInputStream objIn = new ObjectInputStream( byteIn );
+               return objIn.readObject();
+       }
+
+       /**
+        * Create and return object's simple name
+        * 
+        * Use 4 hash value instead of 8 hash value
+        * 
+        * @param obj object to convert
+        * 
+        * @return textual string for <code>obj</code>
+        */
+       public static
+       String
+       toString(
+               final Object obj
+       )
+       {
+               if ( null == obj )
+               {
+                       return NULL_STRING;
+               }
+               final StringBuilder builder = new StringBuilder();
+               builder.append( obj.getClass().getSimpleName() );
+               builder.append( '@' );
+               int hash = obj.hashCode();
+               
+               for ( int i = 8 ; i>=0 ; i-=8 )
+               {
+                       StringUtil.appendHexa( builder, 0xFF & ( hash >> i ) );
+               }
+               
+               
+               return builder.toString();
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/ParsingUtil.java b/org.tizen.common/src/org/tizen/common/util/ParsingUtil.java
new file mode 100644 (file)
index 0000000..6d91b94
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+*  Common
+*
+* 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.common.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 );
+               try
+               {
+                       return Integer.decode( trimmed );
+               } catch ( final Throwable e )
+               {
+                       return defaultValue;
+               }
+       }
+       
+       /**
+        * 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 Throwable 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 Throwable e )
+               {
+                       return defaultValue;
+               }
+               
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/PluginUtil.java b/org.tizen.common/src/org/tizen/common/util/PluginUtil.java
new file mode 100644 (file)
index 0000000..a451c48
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Kangho Kim <kh5325.kim@samsung.com>
+* Ho Namkoong <ho.namkoong@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.common.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.tizen.common.Surrogate;
+
+/**
+ * PluginUtil 
+ * 
+ * This is a util class for handle extension points of the plugins. 
+ *  
+ * @author Ho Namkoong{@literal <ho.namkoong@samsung.com>} (S-Core)
+ */
+public class PluginUtil {
+    
+    protected static Surrogate<IExtensionRegistry> platformSurrogate = new Surrogate<IExtensionRegistry>() {
+        public IExtensionRegistry getAdapter()
+        {
+            return Platform.getExtensionRegistry();
+        }
+    };
+    
+    /**
+     * Return classes of specific extension point id.  
+     * @param extPointId  - extension point id.
+     * @return object array of classes of extPointId.
+     */
+    public static Object[] loadClasses(String extPointId) throws CoreException {
+        IExtensionRegistry registry = platformSurrogate.getAdapter();
+        IExtensionPoint ep = registry.getExtensionPoint(extPointId );
+        IExtension[] exts = ep.getExtensions();
+        List<Object> classList = new ArrayList<Object>();
+        
+        for ( IExtension ext : exts )
+        {
+            IConfigurationElement[] configs = ext.getConfigurationElements();
+            
+            for ( final IConfigurationElement config : configs )
+            {
+                Object cls = (Object) config.createExecutableExtension( "class" );
+                classList.add(cls);
+            }
+        }
+        
+        return classList.toArray();
+    }
+    
+    /**
+     * Return class of specific class id which extends specific extension point id.  
+     * @param extPointId  - extension point id.
+     * @param classId  - class id.
+     * @return object class of specific class id which extends specific extension point id.
+     */
+    public static Object loadClass(String extPointId, String classId) throws CoreException {
+        IExtensionRegistry registry = platformSurrogate.getAdapter();
+        IExtensionPoint ep = registry.getExtensionPoint(extPointId );
+        IExtension[] exts = ep.getExtensions();
+        
+        for ( IExtension ext : exts )
+        {
+            IConfigurationElement[] configs = ext.getConfigurationElements();
+            
+            for ( final IConfigurationElement config : configs )
+            {
+                String id = config.getAttribute("id");
+                if(id != null && id.equals(classId)) {
+                    return (Object) config.createExecutableExtension( "class" );
+                }
+            }
+        }
+        return null;
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/ProjectUtil.java b/org.tizen.common/src/org/tizen/common/util/ProjectUtil.java
new file mode 100644 (file)
index 0000000..31acf7d
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Jihoon Song <jihoon80.song@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.common.util;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.tizen.common.util.log.Logger;
+
+/**
+ * ProjectUtil.
+ * 
+ * Helper related to the Eclipse Project (.project)
+ * 
+ * @author Jihoon Song{@literal <jihoon80.song@samsung.com>} (S-Core)
+ */
+public class ProjectUtil {
+    
+    /**
+     * Null safety project description getter. If project is null, return null.
+     * @param project
+     * @return IProjectDescription
+     * @throws CoreException
+     */
+    public static IProjectDescription getDescription(IProject project) throws CoreException {
+        return (project != null) ? project.getDescription() : null;
+    }
+    
+    /**
+     * Null safety project build specification getter
+     * @param project
+     * @return ICommand[]
+     * @throws CoreException
+     */
+    public static ICommand[] getBuildSpec(IProject project) throws CoreException {
+        IProjectDescription description = getDescription( project );
+        return (description != null) ? description.getBuildSpec() : new ICommand[0];
+    }
+    
+    /**
+     * Build specification setter
+     * @param project
+     * @param commands
+     * @param monitor a progress monitor, or <code>null</code> if progress reporting is not desired
+     * @throws CoreException
+     */
+    public static void setBuildSpec(IProject project, ICommand[] commands, IProgressMonitor monitor)
+            throws CoreException {
+        IProjectDescription description = getDescription( project );
+        if ( description != null ) { // if project or project description is not null
+            description.setBuildSpec( commands );
+            project.setDescription( description, monitor );
+        }
+    }
+    
+    /**
+     * Null safety build command adder
+     * @param oldCommands
+     * @param newCommand
+     * @return ICommand[]
+     */
+    public static ICommand[] addCommand(ICommand[] oldCommands, ICommand newCommand) {
+        // if newCommand is Null
+        if ( newCommand == null ) {
+            if ( oldCommands == null ) { // if argument is Null both, return 0-based array
+                return new ICommand[0];
+            } else {
+                return oldCommands; 
+            }
+        }
+        
+        // create expanded commands
+        ICommand[] newCommands;
+        if ( oldCommands != null ) {
+            newCommands = new ICommand[ oldCommands.length + 1 ];
+            System.arraycopy( oldCommands, 0, newCommands, 0, oldCommands.length );
+        } else {
+            newCommands = new ICommand[ 1 ];
+        }
+        
+        // add new command to last index
+        newCommands[ newCommands.length - 1 ] = newCommand;
+        
+        return newCommands;
+    }
+    
+    /**
+     * Null safety build command finder. If not found, return null.
+     * @param commands
+     * @param builderID
+     * @return ICommand
+     */
+    public static ICommand findCommand(ICommand[] commands, String builderID) {
+        if ( commands != null ) {
+            for (ICommand command : commands) {
+                String builderName = command.getBuilderName();
+                if ( builderName != null && builderName.equals( builderID ) ){ 
+                    return command;
+                }
+            }
+        }
+        
+        return null;
+    }
+    
+    /**
+     * Null safety build command creater. If project or project description is null, return null.
+     * @param project
+     * @return ICommand
+     * @throws CoreException
+     */
+    public static ICommand newCommand(IProject project) throws CoreException {
+        IProjectDescription description = getDescription( project );
+        return (description != null) ? description.newCommand() : null;
+    }
+    
+    /**
+     * Specific build command adder with arguments. If builder ID already exist or is null, ignore this process.
+     * @param project
+     * @param builderID a builder name
+     * @param args a table of command arguments (keys and values must both be of type <code>String</code>), or <code>null</code>
+     * @param monitor a progress monitor, or <code>null</code> if progress reporting is not desired
+     */
+    public static void setBuildCommandWithArgument(IProject project, String builderID,
+            Map<String, String> args, IProgressMonitor monitor) {
+        if ( builderID == null ) { // If builder ID is null
+            return ;
+        }
+        
+        try {
+            ICommand[] commands = getBuildSpec( project );
+            
+            ICommand findedCommand = findCommand( commands, builderID );
+            if ( findedCommand != null ) { // If builder ID already exist
+                return;
+            }
+            
+            ICommand command = newCommand( project );
+            if ( command == null ) {
+                return;
+            }
+            
+            command.setBuilderName( builderID );
+            command.setArguments( args );
+            
+            ICommand[] newCommands = addCommand( commands, command );
+            setBuildSpec( project, newCommands, monitor );
+        } catch (CoreException e) {
+            Logger.log(e);
+        }
+    }
+    
+    /**
+     * Arguments getter in specific build command. If not found, return null.
+     * @param project
+     * @param builderID
+     * @return a table of command arguments (key type : <code>String</code> value type : <code>String</code>), or <code>null</code>
+     */
+    public static Map<String, String> getBuildCommandArgument(IProject project, String builderID) {
+        try {
+            ICommand[] commands = getBuildSpec( project );
+            ICommand command = findCommand( commands, builderID );
+            if ( command != null ) {
+                return command.getArguments();
+            }
+        } catch (CoreException e) {
+            Logger.log(e);
+        }
+        
+        return null;
+    }
+}
index 2f7ac97..9e338c3 100644 (file)
 */
 package org.tizen.common.util;
 
+import static org.tizen.common.util.IOUtil.tryClose;
+
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.FileReader;
 import java.io.FileWriter;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Properties;
@@ -52,11 +53,7 @@ public abstract class PropertyUtil {
                } catch (Exception e) {
                        e.printStackTrace();
                } finally {
-                       if (reader != null)
-                               try {
-                                       reader.close();
-                               } catch (IOException e) {
-                               }
+                       tryClose( reader );
                }
                return props;
        }
@@ -68,11 +65,7 @@ public abstract class PropertyUtil {
                } catch (Exception e) {
                        e.printStackTrace();
                } finally {
-                       if (inputStream != null)
-                               try {
-                                       inputStream.close();
-                               } catch (IOException e) {
-                               }
+                       tryClose( inputStream );
                }
                return props;
        }
@@ -84,11 +77,7 @@ public abstract class PropertyUtil {
                        e.printStackTrace();
                        return false;
                } finally {
-                       if (outputStream != null)
-                               try {
-                                       outputStream.close();
-                               } catch (IOException e) {
-                               }
+                       tryClose( outputStream );
                }
                return true;
        }
@@ -103,11 +92,7 @@ public abstract class PropertyUtil {
                        e.printStackTrace();
                        return false;
                } finally {
-                       if (writer != null)
-                               try {
-                                       writer.close();
-                               } catch (IOException e) {
-                               }
+                       tryClose( writer );
                }
                return true;
        }
diff --git a/org.tizen.common/src/org/tizen/common/util/SWTRunner.java b/org.tizen.common/src/org/tizen/common/util/SWTRunner.java
new file mode 100755 (executable)
index 0000000..ed28682
--- /dev/null
@@ -0,0 +1,44 @@
+package org.tizen.common.util;\r
+\r
+import org.tizen.common.Cabinet;\r
+\r
+abstract public class\r
+SWTRunner<T>\r
+implements Runnable, Cabinet<T>\r
+{\r
+    protected T data;\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.tizen.common.Cabinet#getData()\r
+     */\r
+    @Override\r
+    public\r
+    T\r
+    getData()\r
+    {\r
+        return data;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.tizen.common.Cabinet#setData(java.lang.Object)\r
+     */\r
+    @Override\r
+    public\r
+    void\r
+    setData(\r
+        final T data\r
+    )\r
+    {\r
+        this.data = data;\r
+    }\r
+\r
+    @Override\r
+    public void run()\r
+    {\r
+        setData( process() );\r
+    }\r
+    \r
+    abstract protected T process();\r
+    \r
+\r
+}\r
old mode 100644 (file)
new mode 100755 (executable)
index e9c6f19..4ee8c78
@@ -26,29 +26,206 @@ package org.tizen.common.util;
 
 import java.awt.Dimension;
 import java.awt.Toolkit;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Stack;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.ScrolledComposite;
 import org.eclipse.swt.events.VerifyEvent;
 import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.graphics.Resource;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.tizen.common.Cabinet;
+import org.tizen.common.ui.TableToolTipListener;
 
 
+@SuppressWarnings("restriction")
 public class SWTUtil {
+       
+       private SWTUtil() {}
 
+       // 2012-04-25
+       @Deprecated
     public static final String HTML_EXTENSIONS[] = { "html", "htm", "shtml", "shtm", "xhtml"};
+       
+    protected static final Collection<?> HTML_EXTENSIONS2 =
+       Collections.unmodifiableCollection( new HashSet<Object>( Arrays.asList( HTML_EXTENSIONS ) ) );
+    
+    /**
+     * return {@link Display} in context
+     * 
+     * return new {@link Display} if no {@link Display} in context
+     * 
+     * @return SWT {@link Display} simply
+     * 
+     * @see Display#getCurrent()
+     * @see Display#getDefault();
+     */
+    public static Display getDisplay()
+    {
+       Display dp = Display.getCurrent();
+       if ( null != dp )
+       {
+               return dp;
+       }
+       
+       return Display.getDefault();
+    }
+    
+    /**
+     * <p>
+     * Return active {@link Shell} in context
+     * </p>
+     * @return active {@link Shell}
+     * 
+     * @see #getDisplay()
+     */
+    public static Shell getActiveShell()
+    {
+       final Display dp = getDisplay();
+       if ( null == dp )
+       {
+               return null;
+       }
+       
+       return dp.getActiveShell();
+    }
+    
+    /**
+     * execute {@link Cabinet#run()} and reeturn the result
+     *  
+     * @param runnable object to execute
+     * 
+     * @return result to execute
+     */
+    public static
+    <T>
+    T
+    exec(
+        final Cabinet<T> runnable
+    )
+    {
+        syncExec( (Runnable) runnable );
+        
+        return runnable.getData();
+    }
+    
+    /**
+     * execute {@link Runnable} in SWT thread synchronously
+     * 
+     * @param runnable object to execute
+     */
+    public static void syncExec( final Runnable runnable )
+    {
+       syncExec( getDisplay(), runnable );
+    }
+    
+    /**
+     * execute {@link Runnable} in SWT thread synchronously
+     *
+     * @param dp SWT <code>Display</code>
+     * @param runnable object to execute
+     */
+    public static void syncExec( final Display dp, final Runnable runnable )
+    {
+       dp.syncExec( runnable );
+    }
+    
+    /**
+     * execute {@link Runnable} in SWT thread asynchronously
+     * 
+     * @param runnable object to execute
+     */
+    public static void asyncExec( final Runnable runnable )
+    {
+       asyncExec( getDisplay(), runnable );
+    }
+    
+    /**
+     * execute {@link Runnable} in SWT thread asynchronously
+     * 
+     * @param dp SWT <code>Display</code>
+     * @param runnable object to execute
+     */
+    public static void asyncExec( final Display dp, final Runnable runnable )
+    {
+       dp.asyncExec( runnable );
+    }
+    
+    /**
+     * dispose {@link Widget}s
+     * 
+     * @param disposables {@link Widget}s to dispose
+     */
+    public static void tryDispose( final Widget... disposables )
+    {
+       if ( null == disposables )
+       {
+               return ;
+       }
+       
+       for ( final Widget disposable : disposables )
+       {
+               if ( null == disposable || disposable.isDisposed() )
+               {
+                       continue;
+               }
+               
+               disposable.dispose();
+       }
+    }
+
+    /**
+     * dispose {@link Resource}s
+     * 
+     * @param disposables {@link Resource}s to dispose
+     */
+    public static void tryDispose( final Resource... disposables )
+    {
+        if ( null == disposables )
+        {
+            return ;
+        }
+
+        for ( final Resource disposable : disposables )
+        {
+            if ( null == disposable || disposable.isDisposed() )
+            {
+                continue;
+            }
+
+            disposable.dispose();
+        }
+    }
 
     /**
      * Creates SWT <code>Text</code> for input limited digit.
@@ -80,6 +257,7 @@ public class SWTUtil {
 
     /**
      * Creates SWT <code>ScrolledComposite</code>.
+     * 
      * @param width the minimum width or 0 for default width (0 is screen width)
      * @param height the minimum height or 0 for default height (0 is screen height)
      * @return <code>ScrolledComposite</code>
@@ -103,6 +281,24 @@ public class SWTUtil {
 
         return sc;
     }
+    
+    /**
+     * Get current active page.
+     * 
+     * return null if no active page
+     * 
+     * @return active page
+     */
+    public static IWorkbenchPage getActivePage()
+    {
+        final IWorkbenchWindow window = ViewUtil.getWorkbenchWindow();
+        
+        if ( null == window )
+        {
+               return null;
+        }
+        return window.getActivePage();
+    }
 
     /**
      * Get current active editor.
@@ -111,21 +307,15 @@ public class SWTUtil {
      * @author Changhyun Lee {@literal <changhyun1.lee@samsung.com>} (S-Core)
      */
     public static IEditorPart getActiveEditor() {
-        IWorkbenchWindow window = ViewUtil.getWorkbenchWindow();
-        IWorkbenchPage page = window.getActivePage();
-
-        if(page == null){
-            return null;
-        }
-
-        IEditorPart editor = page.getActiveEditor();
-        if(editor == null){
+        final IWorkbenchPage page = getActivePage();
+        if(page == null )
+        {
             return null;
         }
 
-        return editor;
+        return page.getActiveEditor();
     }
-
+    
     /**
      * Get editor of file extension.
      *
@@ -175,17 +365,9 @@ public class SWTUtil {
      * @author Changhyun Lee {@literal <changhyun1.lee@samsung.com>} (S-Core)
      */
     public static boolean isHtmlFile(String fullName) {
-        String fileExt = FileUtil.getFileExtension(fullName);
-        if (fileExt == null) {
-            return false;
-        }
+        String fileExt = StringUtil.nvl( FileUtil.getFileExtension(fullName) );
 
-        for (String htmlExt : HTML_EXTENSIONS) {
-            if (htmlExt.equalsIgnoreCase(fileExt)) {
-                return true;
-            }
-        }
-        return false;
+        return HTML_EXTENSIONS2.contains( fileExt.toLowerCase() );
     }
 
     /**
@@ -239,4 +421,72 @@ public class SWTUtil {
 
         return projectPath;
     }
-}
\ No newline at end of file
+    
+    public static void addTableToolTipListener(Table table, TableToolTipListener listener) {
+        listener.setTable(table);
+        table.addListener(SWT.MouseMove, listener);
+        table.addListener(SWT.MouseWheel, listener);
+        table.addListener(SWT.Dispose, listener);
+        table.addListener(SWT.MouseHover, listener);
+    }
+    
+    /**
+     * Expands tree and its sub treeitems.
+     *
+     * @param tree target tree to expand.
+     * @author Ho Namkoong {@literal <ho.namkoong@samsung.com>} (S-Core)
+     */
+    public static void expandTree(Tree tree) {
+        if(tree == null) {
+            return;
+        }
+        for(TreeItem treeitem: tree.getItems()) {
+            expandTreeItem(treeitem);
+        }
+    }
+
+    private static void expandTreeItem(TreeItem treeItem) {
+        Stack<TreeItem> treeStack = new Stack<TreeItem>();
+        treeStack.add(treeItem);
+        TreeItem selectedItem = null;
+        
+        do {
+            selectedItem = treeStack.pop();
+            selectedItem.setExpanded(true);
+            
+            if(selectedItem.getItems() != null && selectedItem.getItemCount() != 0) {
+                for (TreeItem childItem : selectedItem.getItems()) {
+                    treeStack.add(childItem);
+                }
+            }
+        } while (!treeStack.isEmpty());
+    }
+    
+    /**
+     * Make error dialog which prints stack trace of the throwable 
+     *
+     * @param title title of the dialog
+     * @param msg message of the dialog
+     * @param t throwable diaog prints out 
+     * @param shell parent shell of this dialog
+     * @author Ho Namkoong {@literal <ho.namkoong@samsung.com>} (S-Core)
+     */
+    public static void errorDialogWithStackTrace(String title, String msg, Throwable t, String pluginId, Shell shell) {
+        
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        t.printStackTrace(pw);
+        
+        final String trace = sw.toString();
+        
+        List<Status> childStatuses = new ArrayList<Status>();
+        
+        for(String line: trace.split("\n")) {
+            childStatuses.add(new Status(IStatus.ERROR, pluginId, line));
+        }
+        
+        MultiStatus ms = new MultiStatus(pluginId, IStatus.ERROR, childStatuses.toArray(new Status[] {}), t.getLocalizedMessage(), t);
+        
+        ErrorDialog.openError(shell, "Error Dialog", msg, ms);
+    }
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/SdbCommandUtil.java b/org.tizen.common/src/org/tizen/common/util/SdbCommandUtil.java
new file mode 100644 (file)
index 0000000..4e25456
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Gun Kim <gune.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.common.util;
+
+import java.io.File;
+
+import org.tizen.common.core.application.InstallPathConfig;
+import org.tizen.sdblib.IDevice;
+
+/**
+ * SdbCommandUtil.
+ * 
+ * sdb helper
+ * 
+ * @author Gun Kim{@literal <gune.kim@samsung.com>} (S-Core)
+ */
+public class SdbCommandUtil {
+    
+    /**
+     * push file to device
+     * 
+     * @param device
+     * 
+     * @param source source file path
+     *  
+     * @param dest destination file path
+     */
+    public static boolean filePush(IDevice device, String source, String dest){
+        final String command_format = InstallPathConfig.getSDBPath() + " -s %s push %s %s ";
+        if ( device == null ) {
+            return false;
+        }
+        
+        if ( !(new File(source).exists()) ) {
+            return false;
+        }
+        
+        String command = String.format(command_format, device.getSerialNumber(), source, dest);
+        if (OSChecker.isUnix() ) {
+            command += "1>/dev/null";
+        }
+        else if (OSChecker.isWindows() ) {
+            command += "1>NUL";
+        }
+        String command_result = HostUtil.returnExecute(command);
+        
+        if ( "".equals(command_result)) {
+            return true;
+        }
+        
+        return false;
+    }
+}
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index deae677..da25324
@@ -24,6 +24,8 @@
 */
 package org.tizen.common.util;
 
+import static org.tizen.common.util.IOUtil.tryClose;
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
@@ -50,23 +52,26 @@ public class StreamGobbler extends Thread
        public void run()
        {
                StringBuffer buffer = new StringBuffer();
+               BufferedReader br = null;
                try {           
                        synchronized (synchronizer) {
-                               BufferedReader br = new BufferedReader(new InputStreamReader(is));
+                               br = new BufferedReader(new InputStreamReader(is));
                                String line;
                                while ( (line = br.readLine()) != null) {
                                        buffer.append(line);
                                        buffer.append("\n");
                                        
                                        if ( os != null )
+                                       {
                                                os.write( (line + "\n").getBytes());
+                                       }
                                }
-                               br.close();
                        }
                } catch (IOException ioe) {
                        ioe.printStackTrace();
                } finally {
                        result = buffer.toString();
+                       tryClose( br );
                }
        }
        public String getResult() {
old mode 100644 (file)
new mode 100755 (executable)
index c7ccee2..8b97822
@@ -28,10 +28,14 @@ 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;
 
+import org.tizen.common.util.log.Logger;
+
 /**
  * @author Changhyun Lee {@literal <changhyun1.lee@samsung.com>} (S-Core)
  *  <ul>
@@ -41,57 +45,170 @@ import java.util.StringTokenizer;
  *  @author gyeongseok.seo@samsung.com, S-Core Inc. 
  *  <ul>
  *  <li> added split method.
+ *  <li> added removeStart method.
  *  </ul> 
  */
-public class StringUtil {
-    public static String trimToNull(String s) {
-        return trimToNull(s, null);
-    }
+public class StringUtil
+{
+    /**
+     * Empty String
+     */
+    public static final String EMPTY_STRING = "";
 
-    public static String trimToNull(String s, String def) {
-        if (s == null) {
-            return def;
-        }
+    /**
+     * Textual string for <code>null</code>
+     */
+    public static final String NULL_STRING = "<<null>>";
 
-        String t = s.trim();
-        if (t.length() == 0) {
-            return def;
-        }
+    /**
+     * 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 t;
+    /**
+     * 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;
     }
 
-    public static InputStream stringToInputStream(String src) {
-        if (src == null) {
+    /**
+     * 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());
+        return new ByteArrayInputStream( src.getBytes() );
     }
 
-    public static String[] split(String s, String delim) {
-        List<String> list = new ArrayList<String>();
-        StringTokenizer st = new StringTokenizer(s, delim);
-        while (st.hasMoreTokens()) {
-            list.add(st.nextToken());
+    /**
+     * 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 getOnlyNumerics(String str) {
-        if (str == null) {
+    /**
+     * @param str
+     * @return
+     */
+    public static String getOnlyNumerics(
+        final String str
+    )
+    {
+        if ( null == str )
+        {
             return null;
         }
         
-        char c;
-        StringBuilder sb = new StringBuilder();
+        final StringBuilder sb = new StringBuilder();
         
-        for (int i = 0; i < str.length() ; i++) {
-            c = str.charAt(i);
-            if (Character.isDigit(c)) {
-                sb.append(c);
+        ArrayUtil.iterate(
+            ArrayUtil.convertToWrapper( str.toCharArray() ),
+            new IteratingRunner<Character>()
+            {
+                public void run( Character arg )
+                {
+                    if (Character.isDigit( arg )) {
+                        sb.append( arg );
+                    }
+                }
             }
-        }
+        );
+        
         return sb.toString();
     }
 
@@ -104,12 +221,12 @@ public class StringUtil {
         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();          
+        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) {
@@ -122,7 +239,886 @@ public class StringUtil {
         return str;
     }
 
-    public static boolean isEmpty(CharSequence cs) {
-        return cs == null || cs.length() == 0;
+    /**
+     * 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();
+    }
+
+    /**
+     * Extract word in front of <coode>index</code> column in <code>doc</code>
+     *
+     * @param doc full string
+     * @param index column index
+     *
+     * @return word in front of <code>index</code> column
+     */
+    public static
+    String
+    getPreviousWord(
+        final String doc,
+        final int index
+    )
+    {
+        final StringBuilder buffer = new StringBuilder();
+
+        if ( index < 0 || doc.length() < index )
+        {
+            Logger.debug( "Index[{0}] is out of bound :[0:{1}]", index, doc.length() );
+            return "";
+        }
+
+        int ch = 0;
+        boolean bNeedWord = false;
+        if ( index < doc.length() )
+        {
+            ch = doc.charAt( index );
+            bNeedWord =  Character.isWhitespace( ch );
+        }
+        Logger.debug( "Character at index :'{0}'", (char ) ch );
+        for ( int i = index - 1 ; 0 <= i ; --i )
+        {
+            ch = doc.charAt( i );
+
+            if ( Character.isWhitespace( ch ) )
+            {
+                if ( bNeedWord )
+                {
+                    continue;
+                }
+                Logger.debug( "Meet space at column {0}", i );
+                break;
+            }
+            bNeedWord = false;
+            buffer.append( (char) ch );
+        }
+
+        return buffer.reverse().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;
+    }
+
 }
diff --git a/org.tizen.common/src/org/tizen/common/util/ThreadUtil.java b/org.tizen.common/src/org/tizen/common/util/ThreadUtil.java
new file mode 100644 (file)
index 0000000..d51eed7
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+/**
+ * ThreadUtil.
+ * 
+ * Helper related to <code>Thread</code>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+ThreadUtil
+{
+       protected ThreadUtil() {}
+       
+       /**
+        * try to invoke {@link Thread#sleep(long)} in safe
+        * 
+        * handle <code>milliseconds</code> to zero( 0 ) if it is negative 
+        * 
+        * @param milliseconds time to sleep in milliseconds
+        * 
+        * @see Thread#sleep(long)
+        */
+       public static void trySleep( final long milliseconds )
+       {
+               if ( milliseconds <=0 )
+               {
+                       return ;
+               }
+               try {
+                       Thread.sleep( milliseconds );
+               } catch ( InterruptedException e ) {
+               }
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/ValidationUtil.java b/org.tizen.common/src/org/tizen/common/util/ValidationUtil.java
new file mode 100644 (file)
index 0000000..3f2de93
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@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.common.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * ValidationUtil.
+ *
+ * Verification Using a regular expression.
+ *
+ * @author Changhyun Lee {@literal <changhyun1.lee@samsung.com>} (S-Core)
+ */
+public class ValidationUtil {
+
+    /**
+     * Check for Email address. RFC 2822 (simplified)Matches a normal email address. Does not check the top-level domain.
+     *
+     * @param value email string
+     *
+     * @return if value is valied email
+     */
+    public static boolean checkForEmail(String value) {
+        String regex = "[A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])??"; //$NON-NLS-1$
+        Pattern pattern = Pattern.compile(regex);
+        Matcher matcher = pattern.matcher(value);
+
+        return matcher.matches();
+    }
+
+    /**
+     * Check for URL string.
+     *
+     * @param value url string
+     *
+     * @return if value is valied url
+     */
+    public static boolean checkForURL(String value) {
+        String regex = "\\b(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; //$NON-NLS-1$
+        Pattern pattern = Pattern.compile(regex);
+        Matcher matcher = pattern.matcher(value);
+
+        return matcher.matches();
+    }
+
+    /**
+     * Check for File extension.
+     *
+     * @param value file name
+     * @param extensions valied file extensions
+     *
+     * @return if value is valied file
+     */
+    public static boolean checkForFileExtension(String value, String[] extensions) {
+        if (StringUtil.isEmpty(value) || extensions == null) {
+            return false;
+        }
+
+        for (String ext : extensions) {
+            if (value.endsWith(ext)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
index 05a3ae5..1bb30fb 100644 (file)
@@ -25,7 +25,6 @@
 package org.tizen.common.util;
 
 import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IViewPart;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPage;
@@ -41,9 +40,9 @@ public class ViewUtil {
         ViewRunnable runnable = new ViewRunnable(id);
 
         if (sync) {
-            Display.getDefault().syncExec(runnable);
+               SWTUtil.syncExec( runnable );
         } else {
-            Display.getDefault().asyncExec(runnable);
+               SWTUtil.asyncExec( runnable );
         }
     }
 
@@ -94,15 +93,17 @@ public class ViewUtil {
     }
 
     public static IWorkbenchWindow getWorkbenchWindow() {
-        IWorkbench workbench = PlatformUI.getWorkbench();
-        IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
-        if (window == null) {
-            if (workbench.getWorkbenchWindowCount() == 1) {
-                window = workbench.getWorkbenchWindows()[0];
-            }
+        final IWorkbench workbench = PlatformUI.getWorkbench();
+        final IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+        if ( window != null )
+        {
+               return window;
         }
-
-        return window;
+        if ( workbench.getWorkbenchWindowCount() == 0 )
+        {
+               return null;
+        }
+        return workbench.getWorkbenchWindows()[0];
     }
 
-}
\ No newline at end of file
+}
 * - S-Core Co., Ltd\r
 *\r
 */\r
-package org.tizen.common.cache;\r
+package org.tizen.common.util.cache;\r
 \r
 import java.util.HashMap;\r
-import java.util.Iterator;\r
 import java.util.Map;\r
 \r
 import org.eclipse.swt.graphics.Color;\r
 import org.eclipse.swt.graphics.RGB;\r
-import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.tizen.common.util.SWTUtil;\r
 \r
 /**\r
  * Class for caching colors\r
@@ -41,33 +41,20 @@ import org.eclipse.swt.widgets.Display;
  */\r
 public final class ColorCache {\r
 \r
-    public static final RGB        BLACK = new RGB(0, 0, 0);\r
-    public static final RGB        WHITE = new RGB(255, 255, 255);\r
+    public static final RGB BLACK = new RGB(0, 0, 0);\r
+    public static final RGB WHITE = new RGB(255, 255, 255);\r
 \r
-    private static Map<RGB, Color> _colorTable;\r
-    private static ColorCache      _instance;\r
-\r
-    static {\r
-        _colorTable = new HashMap<RGB, Color>();\r
-        new ColorCache();\r
-    }\r
+    private static Map<RGB, Color> _colorTable = new HashMap<RGB, Color>();\r
 \r
     private ColorCache() {\r
-        _instance = this;\r
-    }\r
-\r
-    public static ColorCache getInstance() {\r
-        return _instance;\r
     }\r
 \r
     /**\r
      * Disposes of all colors. DO ONLY CALL THIS WHEN YOU ARE SHUTTING DOWN YOUR\r
      * APPLICATION!\r
      */\r
-    public static void disposeColors() {\r
-        Iterator<Color> e = _colorTable.values().iterator();\r
-        while (e.hasNext())\r
-            e.next().dispose();\r
+    synchronized public static void disposeColors() {\r
+       SWTUtil.tryDispose( _colorTable.values().toArray( new Widget[0]) );\r
 \r
         _colorTable.clear();\r
     }\r
@@ -80,27 +67,27 @@ public final class ColorCache {
         return getColorFromRGB(new RGB(0, 0, 0));\r
     }\r
 \r
-    public static Color getColorFromRGB(RGB rgb) {\r
+    synchronized public static Color getColorFromRGB(RGB rgb) {\r
         Color color = _colorTable.get(rgb);\r
 \r
         if (color == null) {\r
-            color = new Color(Display.getCurrent(), rgb);\r
+            color = new Color( SWTUtil.getDisplay(), rgb);\r
             _colorTable.put(rgb, color);\r
         }\r
 \r
         return color;\r
     }\r
 \r
-    public static Color getColor(int r, int g, int b) {\r
+    synchronized public static Color getColor(int r, int g, int b) {\r
         RGB rgb = new RGB(r, g, b);\r
         Color color = _colorTable.get(rgb);\r
 \r
         if (color == null) {\r
-            color = new Color(Display.getCurrent(), rgb);\r
+            color = new Color( SWTUtil.getDisplay(), rgb);\r
             _colorTable.put(rgb, color);\r
         }\r
 \r
         return color;\r
     }\r
-\r
-}
\ No newline at end of file
+    \r
+}\r
old mode 100644 (file)
new mode 100755 (executable)
similarity index 83%
rename from org.tizen.common/src/org/tizen/common/cache/FontCache.java
rename to org.tizen.common/src/org/tizen/common/util/cache/FontCache.java
index ec5b81a..5a83a77
 * - S-Core Co., Ltd\r
 *\r
 */\r
-package org.tizen.common.cache;\r
+package org.tizen.common.util.cache;\r
+\r
+import static org.tizen.common.util.SWTUtil.tryDispose;\r
 \r
 import java.util.ArrayList;\r
 import java.util.List;\r
 \r
 import org.eclipse.swt.graphics.Font;\r
 import org.eclipse.swt.graphics.FontData;\r
-import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.tizen.common.util.SWTUtil;\r
 \r
 /**\r
  * Caching class for fonts. Also deals with re-creating fonts should they have been disposed when the \r
@@ -47,12 +50,8 @@ public class FontCache {
      * Disposes all fonts and clears out the cache. Never call this unless you are shutting down your \r
      * code/client/etc.\r
      */\r
-    public static void disposeAll() {\r
-        for (OneFont of : _existing) {\r
-            if (of.getFont() != null && !of.getFont().isDisposed()) {\r
-                of.getFont().dispose();\r
-            }\r
-        }\r
+    synchronized public static void disposeAll() {\r
+       SWTUtil.tryDispose( _existing.toArray( new Widget[0] ) );\r
 \r
         _existing.clear();\r
     }\r
@@ -63,7 +62,7 @@ public class FontCache {
      * @param fd FontData\r
      * @return Font or null on error\r
      */\r
-    public static Font getFont(FontData fd) {\r
+    synchronized public static Font getFont(FontData fd) {\r
         try {\r
             boolean disposed = false;\r
             OneFont toRemove = null;\r
@@ -92,7 +91,7 @@ public class FontCache {
         return null;\r
     }\r
 \r
-    public static int getCount() {\r
+    synchronized public static int getCount() {\r
         return _existing.size();\r
     }\r
 \r
@@ -104,7 +103,10 @@ public class FontCache {
      */\r
     public static Font getFont(Font font) {\r
         try {\r
-            if (font == null || font.isDisposed()) return null;\r
+            if (font == null || font.isDisposed())\r
+            {\r
+                return null;\r
+            }\r
 \r
             FontData fd = font.getFontData()[0];\r
             return getFont(fd);\r
@@ -124,7 +126,7 @@ public class FontCache {
      * @param style Style of font\r
      * @return Font or null on error\r
      */\r
-    public static Font getFont(String fontName, int height, int style) {\r
+    synchronized public static Font getFont(String fontName, int height, int style) {\r
         try {\r
             boolean disposed = false;\r
             OneFont toRemove = null;\r
@@ -165,14 +167,14 @@ class OneFont {
         _name = name;\r
         _height = height;\r
         _style = style;\r
-        _font = new Font(Display.getDefault(), name, height, style);\r
+        _font = new Font( SWTUtil.getDisplay(), name, height, style);\r
     }\r
 \r
     public OneFont(FontData fd) {\r
         _name = fd.getName();\r
         _height = fd.getHeight();\r
         _style = fd.getStyle();\r
-        _font = new Font(Display.getDefault(), fd);\r
+        _font = new Font( SWTUtil.getDisplay(), fd);\r
     }\r
 \r
     public String getName() {\r
diff --git a/org.tizen.common/src/org/tizen/common/util/cache/ImageCache.java b/org.tizen.common/src/org/tizen/common/util/cache/ImageCache.java
new file mode 100644 (file)
index 0000000..7789919
--- /dev/null
@@ -0,0 +1,108 @@
+/*\r
+ *  Common\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * Changhyun Lee <changhyun1.lee@samsung.com>\r
+ * Kangho Kim <kh5325.kim@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.common.util.cache;\r
+\r
+import java.io.InputStream;\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.tizen.common.util.IOUtil;\r
+import org.tizen.common.util.SWTUtil;\r
+\r
+/**\r
+ * Class for caching images\r
+ * \r
+ * @author Emil\r
+ */\r
+public class ImageCache {\r
+\r
+       // what path to get to the "icons" directory without actually including it\r
+       private static final String           ICON_ROOT_PATH = "icons/";\r
+\r
+       private final static HashMap<String, Image> _ImageMap = new HashMap<String, Image>();\r
+\r
+       /**\r
+        * Returns an image that is also cached if it has to be created and does not already exist in the cache.\r
+        * \r
+        * @param fileName Filename of image to fetch\r
+        * @return Image null if it could not be found\r
+        */\r
+       public static Image getImage(String fileName) {\r
+               fileName = ICON_ROOT_PATH + fileName;\r
+               Image image = _ImageMap.get(fileName);\r
+               if (image == null) {\r
+                       image = createImage(fileName);\r
+                       _ImageMap.put(fileName, image);\r
+               }\r
+               return image;\r
+       }\r
+\r
+       /**\r
+        * creates the image, and tries really hard to do so\r
+        * \r
+        * FIXME : substring is not exact expression to remove leading '/'\r
+        * \r
+        * @param fileName image file name\r
+        * \r
+        * @return loaded <code>Image</code>\r
+        */\r
+       synchronized private static Image createImage(String fileName) {\r
+               ClassLoader classLoader = ImageCache.class.getClassLoader();\r
+               InputStream is = classLoader.getResourceAsStream(fileName);\r
+               try\r
+               {\r
+                       if (is == null) {\r
+                               // the old way didn't have leading slash, so if we can't find the image stream,\r
+                               // let's see if the old way works.\r
+                               is = classLoader.getResourceAsStream(fileName.substring(1));\r
+                       }\r
+                       if (is == null) {\r
+                               is = classLoader.getResourceAsStream(fileName);\r
+                               if (is == null) {\r
+                                       is = classLoader.getResourceAsStream(fileName.substring(1));\r
+                                       if (is == null) { return null; }\r
+                               }\r
+                       }\r
+\r
+                       return new Image( SWTUtil.getDisplay(), is);\r
+               }\r
+               finally\r
+               {\r
+                       IOUtil.tryClose( is );\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Disposes ALL images that have been cached.\r
+        */\r
+       synchronized public static void dispose() {\r
+\r
+               SWTUtil.tryDispose( _ImageMap.values().toArray( new Widget[0]) );\r
+               _ImageMap.clear();\r
+\r
+       }\r
+}\r
 * - S-Core Co., Ltd
 *
 */
-package org.tizen.common.manager;
+package org.tizen.common.util.cache;
 
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.widgets.Display;
+import org.tizen.common.util.Assert;
+import org.tizen.common.util.SWTUtil;
 
-public class ColorCache {
+public class NamedColorCache {
        private String[] keys;
        private Color[] colors;
        
-       public ColorCache(String[] keys){
-               if(keys==null||keys.length==0)
-                       throw new IllegalArgumentException(Messages.ColorCache_0);
+       public NamedColorCache(String[] keys){
+               Assert.notEmpty( keys, "Argument must not be null" );
                
                this.keys = keys;
                this.colors = new Color[keys.length];
@@ -71,7 +71,7 @@ public class ColorCache {
                        color=null;
                }
                
-               colors[index] = new Color(Display.getCurrent(),rgb);
+               colors[index] = new Color( SWTUtil.getDisplay(), rgb );
        }
        
        public void dispose(){
diff --git a/org.tizen.common/src/org/tizen/common/util/io/Buffer.java b/org.tizen.common/src/org/tizen/common/util/io/Buffer.java
new file mode 100644 (file)
index 0000000..888d346
--- /dev/null
@@ -0,0 +1,504 @@
+/*
+ * Common
+ *
+ * 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.common.util.io;
+
+import java.io.Closeable;
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.LinkedList;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * Buffer.
+ * 
+ * Buffer for high performance input / output
+ * 
+ * No synchronized and no retention
+ * 
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+Buffer
+implements Closeable
+{
+
+       /**
+        * Logger for this instance
+        */
+       protected Logger logger = LoggerFactory.getLogger( getClass() );
+
+       /**
+        * Pool for {@link ByteBuffer}
+        * @see BufferPool
+        */
+       protected BufferPool pool;
+
+       /**
+        * Used buffers
+        */
+       protected LinkedList<ByteBuffer> useds = new LinkedList<ByteBuffer>();
+
+       /**
+        * in-using read buffer
+        */
+       protected ByteBuffer readBuffer;
+
+       /**
+        * in-using write buffer
+        */
+       protected ByteBuffer writeBuffer;
+
+
+       /**
+        * in-using buffer
+        */
+       protected LinkedList<ByteBuffer> usings = new LinkedList<ByteBuffer>();
+
+       /**
+        * bytes to be read
+        */
+       protected int nReaded = 0;
+
+       /**
+        * total buffer size
+        */
+       protected int size = 0;
+
+       /**
+        * buffer index
+        */
+       protected int index;
+
+       /**
+        * Constructor with {@link BufferPool}
+        * 
+        * @param pool {@link BufferPool}
+        */
+       public
+       Buffer(
+               final BufferPool pool
+       )
+       {
+               this.pool = pool;
+       }
+
+       /**
+        * <p>
+        * Return contents' size in buffer
+        * </p>
+        * 
+        * @return contents' size
+        */
+       public
+       int
+       size()
+       {
+               return this.size;
+       }
+
+       /**
+        * <p>
+        * Return the number of buffer
+        * </p>
+        * @return the number of {@link ByteBuffer}
+        */
+       public
+       int
+       getBufferSize()
+       {
+               return useds.size() + usings.size() + ( ( null == readBuffer )?0:1 ) + ( ( null == writeBuffer )?0:1 );
+       }
+
+       /**
+        * Return in-using {@link ByteBuffer} for writing
+        * 
+        * @return in-using buffer
+        * 
+        * @throws IOException When new buffer can't be created
+        */
+       public
+       ByteBuffer
+       getBufferForWrite()
+       throws IOException
+       {
+               if ( null == writeBuffer )
+               {
+                       writeBuffer = pool.borrow();
+               }
+               else if ( writeBuffer.remaining() <= 0 )
+               {
+                       writeBuffer.flip();
+                       usings.addLast( writeBuffer );
+                       writeBuffer = pool.borrow();
+               }
+
+               return writeBuffer;
+       }
+
+       /**
+        * Return in-using {@link ByteBuffer} for reading
+        * 
+        * @return in-using buffer
+        * 
+        * @throws IOException reserved
+        */
+       public
+       ByteBuffer
+       getBufferForRead()
+       throws IOException
+       {
+               if ( null != readBuffer && 0 == readBuffer.remaining() )
+               {
+                       readBuffer.position( 0 );
+                       useds.add( readBuffer );
+                       readBuffer = null;
+               }
+
+               if ( null == readBuffer )
+               {
+                       if ( usings.isEmpty() )
+                       {
+                               if ( null != writeBuffer )
+                               {
+                                       readBuffer = writeBuffer;
+                                       readBuffer.flip();
+                                       writeBuffer = null;
+                               }
+                               else
+                               {
+                                       return null;
+                               }
+                       }
+                       else
+                       {
+                               readBuffer = usings.removeFirst();
+                       }
+               }
+
+               return readBuffer;
+       }
+
+       /**
+        * Read bytes from <code>channel</code>
+        * 
+        * @param channel {@link SocketChannel}
+        * 
+        * @return the number character to read
+        * 
+        * @throws IOException When buffer is NOT available
+        */
+       public
+       int
+       readFrom(
+               final SocketChannel channel
+       )
+       throws IOException
+       {
+               int sum = 0;
+               int nCnt = 0;
+               while ( true )
+               {
+                       final ByteBuffer buffer = getBufferForWrite();
+                       int nRead = channel.read( buffer );
+                       if ( nRead < 0 )
+                       {
+                               throw new EOFException();
+                       }
+                       else if ( 0 == nRead )
+                       {
+                               this.size += sum;
+                               if ( 0 < sum )
+                               {
+                                       logger.info( "{} bytes[{}] read from {}", new Object[] { sum, nCnt, channel } );
+                               }
+                               return sum;
+                       }
+                       sum += nRead;
+                       ++nCnt;
+               }
+       }
+
+
+       /**
+        * Write all contents to <code>channel</code>
+        * 
+        * @param channel {@link SocketChannel}
+        * 
+        * @return the number of bytes to write
+        * 
+        * @throws IOException When buffer is NOT available
+        */
+       public
+       int
+       writeTo(
+               final SocketChannel channel
+       ) throws IOException
+       {
+               int sum = 0;
+
+               while ( 0 < size )
+               {
+                       final ByteBuffer buffer = getBufferForRead();
+                       final int nWrite = channel.write( buffer );
+                       if ( 0 < nWrite )
+                       {
+                               this.size -= nWrite;
+                               sum += nWrite;
+                       }
+               }
+
+               nReaded += sum;
+
+               logger.info( "Send {} bytes to {}", sum, channel );
+
+               return sum;
+       }
+
+       /**
+        * Read and return a byte character from buffer
+        * 
+        * @return character to read
+        * 
+        * @throws IOException When buffer is NOT available
+        */
+       public
+       int
+       read()
+       throws IOException
+       {
+               final ByteBuffer buffer = getBufferForRead();
+               if ( null == buffer )
+               {
+                       return -1;
+               }
+
+               int ch = (int) ( 0xFF & buffer.get() );
+               --size;
+               ++nReaded;
+
+               return ch;
+       }
+
+       /**
+        * Read integer from buffer
+        * 
+        * @return integer to read
+        * 
+        * @throws IOException When buffer is NOT available
+        */
+       public
+       int
+       readInt() throws IOException
+       {
+               int i1 = read();
+               int i2 = read();
+               int i3 = read();
+               int i4 = read();
+
+               return ( (int) 0xFF & i1 ) << 24 | ( (int) 0xFF & i2 ) << 16 | ( (int) 0xFF & i3 ) << 8 | ( (int) 0xFF & i4 );
+       }
+
+       /**
+        * Write a byte character to buffer
+        * 
+        * @param value character to write
+        * 
+        * @throws IOException When buffer is NOT available
+        */
+       public
+       void
+       write( final int value ) throws IOException
+       {
+               final ByteBuffer buffer = getBufferForWrite();
+               buffer.put( (byte) value );
+               ++size;
+       }
+
+       /**
+        * Write <code>bytes</code> to buffer
+        * 
+        * @param bytes contents to write
+        * 
+        * @throws IOException When buffer is NOT available
+        */
+       public
+       void
+       write( final byte[] bytes ) throws IOException
+       {
+               for ( int i = 0, n = bytes.length ; i < n ; )
+               {
+                       final ByteBuffer buffer = getBufferForWrite();
+                       final int remaingSize = buffer.remaining();
+                       buffer.put( bytes, i, remaingSize );
+                       i += remaingSize;
+               }
+       }
+
+       /**
+        * Write integer to buffer
+        * 
+        * @param value integer to write
+        * 
+        * @throws IOException When buffer is NOT available
+        */
+       public
+       void
+       writeInt(
+               final int value
+       )
+       throws IOException
+       {
+               write( 0xFF & ( value >> 24 ) );
+               write( 0xFF & ( value >> 16 ) );
+               write( 0xFF & ( value >> 8 ) );
+               write( 0xFF & ( value ) );
+       }
+
+       /**
+        * Reset using resource( buffer, index, ...etc )
+        */
+       public
+       void
+       reset()
+       {
+               if ( null != readBuffer )
+               {
+                       readBuffer.position();
+                       useds.add( readBuffer );
+               }
+
+               useds.addAll( usings );
+
+               if ( null != writeBuffer )
+               {
+                       writeBuffer.flip();
+                       useds.add( writeBuffer );
+                       writeBuffer = null;
+               }
+
+               usings = useds;
+               useds = new LinkedList<ByteBuffer>();
+               size += nReaded;
+               nReaded = 0;
+       }
+
+       /**
+        * Pack unused resource
+        * 
+        * @throws IOException When {@link ByteBuffer} can't be release
+        */
+       synchronized public
+       void
+       pack() throws IOException
+       {
+               for ( final ByteBuffer buffer : useds )
+               {
+                       nReaded -= buffer.remaining();
+                       pool.release( buffer );
+               }
+
+               useds.clear();
+       }
+
+       /* (non-Javadoc)
+        * @see java.io.Closeable#close()
+        */
+       synchronized public
+       void
+       close()
+       throws IOException
+       {
+               if ( null != readBuffer )
+               {
+                       pool.release( readBuffer );
+                       readBuffer = null;
+               }
+               for ( final ByteBuffer buffer : usings )
+               {
+                       pool.release( buffer );
+               }
+               usings.clear();
+               if ( null != writeBuffer )
+               {
+                       pool.release( writeBuffer );
+                       writeBuffer = null;
+               }
+
+               for ( final ByteBuffer buffer : useds )
+               {
+                       pool.release( buffer );
+               }
+
+               useds.clear();
+       }
+       
+       /**
+        * Concatencate buffers
+        * 
+        * @param buffers {@link Buffer}s to concatenate
+        * 
+        * @return {@link Buffer} to be concatenate
+        */
+       public static
+       Buffer
+       concatenate(
+               final Buffer... buffers
+       )
+       {
+               final Buffer ret = new Buffer( null );
+               boolean bInit = false;
+               for ( final Buffer buffer : buffers )
+               {
+                       if ( bInit && ret.pool != buffer.pool )
+                       {
+                               throw new IllegalArgumentException( "Unmatching buffer pool" );
+                       }
+                       ret.pool = buffer.pool;
+                       bInit = true;
+
+                       buffer.reset();
+                       ret.usings.addAll( buffer.usings );
+                       ret.size += buffer.size;
+               }
+
+               return ret;
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       public String toString()
+       {
+               return "Buffer[" + size + "]";
+       }
+}
+
diff --git a/org.tizen.common/src/org/tizen/common/util/io/BufferInputStream.java b/org.tizen.common/src/org/tizen/common/util/io/BufferInputStream.java
new file mode 100644 (file)
index 0000000..32608a9
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Common
+ *
+ * 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.common.util.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * <p>
+ * BufferInputStream.
+ * 
+ * {@link InputStream} to use {@link Buffer}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see Buffer
+ */
+public class
+BufferInputStream
+extends InputStream
+{
+       /**
+        * buffer to store bytes
+        */
+       protected final Buffer buffer;
+
+       /**
+        * Constructor with buffer
+        * 
+        * @param buffer {@link ByteBuffer}
+        */
+       public
+       BufferInputStream(
+               final Buffer buffer
+       )
+       {
+               if ( null == buffer )
+               {
+                       throw new NullPointerException();
+               }
+
+               this.buffer = buffer;
+       }
+
+       /* (non-Javadoc)
+        * @see java.io.InputStream#read()
+        */
+       @Override
+       public
+       int
+       read()
+       throws IOException
+       {
+               return buffer.read();
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/io/BufferOutputStream.java b/org.tizen.common/src/org/tizen/common/util/io/BufferOutputStream.java
new file mode 100644 (file)
index 0000000..3a4a195
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Common
+ *
+ * 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.common.util.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * <p>
+ * BufferOutputStream.
+ * 
+ * {@link OutputStream} to use {@link Buffer}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see Buffer
+ */
+public class
+BufferOutputStream
+extends OutputStream
+{
+       /**
+        * buffer to store bytes
+        */
+       protected Buffer buffer;
+
+       /**
+        * Constructor with buffer
+        * 
+        * @param buffer {@link ByteBuffer}
+        */
+       public
+       BufferOutputStream(
+               final Buffer buffer
+       )
+       {
+               if ( null == buffer )
+               {
+                       throw new NullPointerException();
+               }
+               this.buffer = buffer;
+       }
+
+       /**
+        * Return internal buffer
+        * 
+        * @return {@link Buffer}
+        */
+       public
+       Buffer
+       getBuffer()
+       {
+               return this.buffer;
+       }
+
+       /* (non-Javadoc)
+        * @see java.io.OutputStream#write(int)
+        */
+       @Override
+       public
+       void
+       write(
+               final int b
+       )
+       throws IOException
+       {
+               buffer.write( b );
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/io/BufferPool.java b/org.tizen.common/src/org/tizen/common/util/io/BufferPool.java
new file mode 100644 (file)
index 0000000..ee6d938
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Common
+ *
+ * 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.common.util.io;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.pool.BasePoolableObjectFactory;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPoolFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * BufferPool.
+ * 
+ * Pool for {@link Buffer}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ */
+public class
+BufferPool
+implements Closeable
+{
+
+       /**
+        * The default number of buffer fragments
+        */
+       protected static final int N_CREATION = 1024;
+
+       /**
+        * Buffer fragment's  default size
+        */
+       protected static final int BUFFER_SIZE = 256;
+
+       /**
+        * Logger for this instance
+        */
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+
+       /**
+        * The number of buffer fragements to create
+        */
+       protected int nCreation = N_CREATION;
+
+       /**
+        * Buffer fragement's size
+        */
+       protected int bufferSize = BUFFER_SIZE;
+
+       /**
+        * Set the number of fragment
+        * 
+        * @param nCreation the number of fragment
+        */
+       public
+       void
+       setNumberOfFragments(
+               final int nCreation
+       )
+       {
+               this.nCreation = nCreation;
+       }
+
+       /**
+        * Set buffer fragment's size
+        * @param bufferSize buffer fargement's size
+        */
+       public
+       void
+       setSizeOfFragment(
+               final int bufferSize
+       )
+       {
+               this.bufferSize = bufferSize;
+       }
+
+       /**
+        * Pool for {@link ByteBuffer}
+        */
+       protected final ObjectPool<ByteBuffer> bufferPool =
+               new GenericObjectPoolFactory<ByteBuffer>( new BasePoolableObjectFactory<ByteBuffer>() {
+
+                       protected final LinkedList<ByteBuffer> buffers = new LinkedList<ByteBuffer>();
+
+                       /* (non-Javadoc)
+                        * @see org.apache.commons.pool.BasePoolableObjectFactory#makeObject()
+                        */
+                       @Override
+                       public
+                       ByteBuffer
+                       makeObject()
+                       throws Exception
+                       {
+                               logger.trace( "{} buffer(s) exist", buffers.size() );
+                               if ( !buffers.isEmpty() )
+                               {
+                                       return buffers.removeFirst();
+                               }
+
+                               final long startTime = System.currentTimeMillis();
+                               final int totalSize = nCreation * bufferSize;
+
+                               final ByteBuffer totalBuffer = ByteBuffer.allocateDirect( totalSize );
+
+                               for ( int limit = bufferSize ; limit <= totalSize ; limit += bufferSize )
+                               {
+                                       totalBuffer.limit( limit );
+                                       buffers.add( totalBuffer.slice() );
+                                       totalBuffer.position( limit );
+                               }
+
+                               final long endTime = System.currentTimeMillis();
+                               logger.info( "Buffer creation time :{} ms", ( endTime - startTime ) );
+
+                               return buffers.removeFirst();
+                       }
+
+
+                       /* (non-Javadoc)
+                        * @see org.apache.commons.pool.BasePoolableObjectFactory#activateObject(java.lang.Object)
+                        */
+                       public
+                       void
+                       activateObject(
+                               final ByteBuffer buffer
+                       )
+                       throws Exception
+                       {
+                               super.activateObject( buffer );
+
+                               buffer.clear();
+                       }
+                       
+               }, -1 ).createPool();
+
+       /**
+        * Pick-up and return {@link ByteBuffer} from pool
+        * 
+        * @return {@link ByteBuffer}
+        * 
+        * @throws IOException When {@link ByteBuffer} can't be created or available
+        */
+       public
+       ByteBuffer
+       borrow()
+       throws IOException
+       {
+               try
+               {
+                       return bufferPool.borrowObject();
+               }
+               catch (
+                       final Exception e
+               )
+               {
+                       throw new IOException( e );
+               }
+       }
+
+       /**
+        * Release buffer to pool
+        * 
+        * @param buffer {@link ByteBuffer} to release
+        * 
+        * @throws IOException When {@link ByteBuffer} can't be release
+        */
+       public
+       void
+       release(
+               final ByteBuffer buffer
+       ) throws IOException
+       {
+               try
+               {
+                       bufferPool.returnObject( buffer );
+               }
+               catch
+               (
+                       final Exception e
+               )
+               {
+                       throw new IOException( e );
+               }
+       }
+
+       /* (non-Javadoc)
+        * @see java.io.Closeable#close()
+        */
+       @Override
+       public
+       void
+       close()
+       throws IOException
+       {
+
+               try {
+                       bufferPool.close();
+               } catch (
+                       final Exception e
+               )
+               {
+                       throw new IOException( e );
+               }
+
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public
+       String
+       toString()
+       {
+               return ObjectUtils.toString( this );
+       }
+
+
+}
@@ -23,7 +23,7 @@
 *
 */
 
-package org.tizen.common.log;
+package org.tizen.common.util.log;
 
 import java.text.MessageFormat;
 
@@ -31,7 +31,7 @@ import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.tizen.common.CommonPlugin;
-import org.tizen.common.console.ConsoleManager;
+import org.tizen.common.ui.view.console.ConsoleManager;
 
 
 /**
@@ -74,6 +74,11 @@ public class Logger {
             log(new Status(IStatus.ERROR, getCallerName(), e.toString(), e));
         }
     }
+    
+    public static void debug( String message, Object... arguments )
+    {
+       
+    }
 
     public static void info(String message, Object... arguments) {
         log(new Status(Status.INFO, getCallerName(), getPossiblyFormattedString(message, arguments)));
diff --git a/org.tizen.common/src/org/tizen/common/util/url/classpath/Connection.java b/org.tizen.common/src/org/tizen/common/util/url/classpath/Connection.java
new file mode 100644 (file)
index 0000000..55b015f
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+*  Common
+*
+* 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.common.util.url.classpath;
+
+import static org.tizen.common.util.StringUtil.removeLastSegment;
+import static org.tizen.common.util.StringUtil.trimLeadingCharacter;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.util.Assert;
+
+/**
+ * Connection.
+ * 
+ * {@link URLConnection} for classpath url
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+Connection
+extends URLConnection 
+{
+       
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+       
+       protected String fqcn;
+       
+       protected URL internalUrl = null;
+
+       /**
+        * <p>
+        * Constructor with classpath url
+        * </p>
+        * 
+        * @param url url for resouce in classpath
+        */
+       protected Connection( final URL url, final String fqcn )
+       {
+               super( url );
+               
+               this.fqcn = fqcn;
+               logger.debug( "Fully qualified class name :{}", fqcn );
+       }
+       
+       /* (non-Javadoc)
+        * @see java.net.URLConnection#connect()
+        */
+       @Override
+       public
+       void
+       connect()
+       throws IOException
+       {
+               Assert.isNull( this.internalUrl );
+               
+               final String path = trimLeadingCharacter( getURL().getPath(), '/' );
+               
+               final Collection<ClassLoader> classLoaders = getClassLoaders();
+               logger.trace( "Classloaders :{}", classLoaders );
+               
+               for ( final ClassLoader cl : classLoaders )
+               {
+                       URL url = cl.getResource( path );
+                       logger.trace( "Check url for {} :{}", path, url );
+                       if ( null == url )
+                       {
+                               continue;
+                       }
+                       
+                       this.internalUrl = url;
+                       connected = true;
+                       return ;
+               }
+               
+               if ( null == fqcn )
+               {
+                       connected = true;
+                       return ;
+               }
+               
+               final String packageName = removeLastSegment( fqcn, "." );
+               final String fullPath = trimLeadingCharacter( packageName.replace( '.', '/' ), '/' ) + "/" + path;
+               logger.trace( "Package name :{}, Full path :{}", packageName, fullPath );
+               
+               for ( final ClassLoader cl : classLoaders )
+               {
+                       URL url = cl.getResource( fullPath );
+                       logger.trace( "Check url for {} :{}", fullPath, url );
+                       if ( null == url )
+                       {
+                               continue;
+                       }
+                       
+                       this.internalUrl = url;
+                       connected = true;
+                       return ;
+               }
+               
+       }
+       
+       /**
+        * <p>
+        * Return classloaders to provide resource<br>
+        * 
+        * ClassLoader is following
+        * <ul>
+        *      <li>Context ClassLoader</li>
+        *      <li>ClassLoader for this class</li>
+        *      <li>SystemClassLoader</li>
+        * </ul>
+        * </p>
+        * 
+        * @return {@link ClassLoader} candidate
+        */
+       protected static Collection<ClassLoader> getClassLoaders()
+       {
+               final LinkedHashSet<ClassLoader> classLoaders = new LinkedHashSet<ClassLoader>();
+               
+               if ( null != Thread.currentThread().getContextClassLoader() )
+               {
+                       classLoaders.add( Thread.currentThread().getContextClassLoader() );
+               }
+               
+               classLoaders.add( Connection.class.getClassLoader() );
+               classLoaders.add( ClassLoader.getSystemClassLoader() );
+               
+               return classLoaders;
+       }
+
+       /* (non-Javadoc)
+        * @see java.net.URLConnection#getInputStream()
+        */
+       @Override
+       public
+       InputStream
+       getInputStream()
+       throws IOException
+       {
+               if ( !connected )
+               {
+                       connect();
+               }
+               if ( null == this.internalUrl )
+               {
+                       throw new IOException( "resource not found" );
+               }
+               logger.trace( "Open stream :{}", internalUrl );
+               
+               return internalUrl.openStream();
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/url/classpath/Handler.java b/org.tizen.common/src/org/tizen/common/util/url/classpath/Handler.java
new file mode 100644 (file)
index 0000000..b87d5ae
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+*  Common
+*
+* 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.common.util.url.classpath;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.util.ObjectUtil;
+
+/**
+ * Handler.
+ * 
+ * {@link URLStreamHandler} for classpath url
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+Handler
+extends URLStreamHandler
+{
+
+       
+       /**
+        * Logger of object
+        */
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+
+       /**
+        * Full qualified class name of caller( exactly caller that call new URL() )
+        */
+       protected final String fqcnOfCaller;
+       
+       public Handler()
+       {
+               fqcnOfCaller = pickupCaller();
+       }
+       
+       protected String pickupCaller()
+       {
+               final StackTraceElement[] callStacks = new Exception().getStackTrace();
+               
+               boolean bUrl = false;
+               
+               for ( final StackTraceElement element : callStacks )
+               {
+                       logger.trace( "Check stack :{}", element );
+                       final String className = element.getClassName();
+                       logger.trace( "Class :{}", className );
+                       
+                       if ( ObjectUtil.equals( className, URL.class.getName() ) )
+                       {
+                               bUrl = true;
+                       }
+                       else if ( bUrl )
+                       {
+                               return className;
+                       }
+               }
+               
+               return null;
+       }
+
+
+       /* (non-Javadoc)
+        * @see java.net.URLStreamHandler#openConnection(java.net.URL)
+        */
+       @Override
+       protected
+       URLConnection
+       openConnection(
+               final URL u
+       )
+       throws IOException
+       {
+               return new Connection( u, fqcnOfCaller );
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/url/cp/Connection.java b/org.tizen.common/src/org/tizen/common/util/url/cp/Connection.java
new file mode 100644 (file)
index 0000000..7c13ac2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+*  Common
+*
+* 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.common.util.url.cp;
+
+import java.net.URL;
+import java.net.URLConnection;
+
+/**
+ * Connection.
+ * 
+ * {@link URLConnection} for classpath url
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see org.tizen.common.util.url.classpath.Connection
+ */
+public class
+Connection
+extends org.tizen.common.util.url.classpath.Connection 
+{
+
+       /**
+        * Constructor with url
+        * 
+        * @param url {@link URL}
+        */
+       protected Connection( final URL url, final String fqcn )
+       {
+               super( url, fqcn );
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/url/cp/Handler.java b/org.tizen.common/src/org/tizen/common/util/url/cp/Handler.java
new file mode 100644 (file)
index 0000000..d2f9686
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+*  Common
+*
+* 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.common.util.url.cp;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+/**
+ * Handler.
+ * 
+ * {@link URLStreamHandler} for classpath url
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see org.tizen.common.util.url.classpath.Handler
+ */
+public class
+Handler
+extends org.tizen.common.util.url.classpath.Handler
+{
+
+       /* (non-Javadoc)
+        * @see java.net.URLStreamHandler#openConnection(java.net.URL)
+        */
+       @Override
+       protected
+       URLConnection
+       openConnection(
+               final URL u
+       )
+       throws IOException
+       {
+               return new Connection( u, fqcnOfCaller );
+       }
+
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/url/vf/Connection.java b/org.tizen.common/src/org/tizen/common/util/url/vf/Connection.java
new file mode 100644 (file)
index 0000000..e32f42d
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+*  Common
+*
+* 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.common.util.url.vf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.file.VirtualFileHandler;
+
+/**
+ * Connection.
+ * 
+ * {@link URLConnection} for {@link VirtualFileHandler}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+Connection
+extends URLConnection 
+{
+
+       /**
+        * Virutal file handler to search
+        */
+       protected static VirtualFileHandler vfHandler = new VirtualFileHandler();
+       
+       /**
+        * Logger for this instance
+        */
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+       
+       /**
+        * Return {@link VirtualFileHandler} to search
+        * 
+        * @return {@link #vfHandler}
+        */
+       public static
+       VirtualFileHandler
+       getVirtualFileHandler()
+       {
+               return vfHandler;
+       }
+       
+       /**
+        * Set {@link VirtualFileHandler} to search
+        * 
+        * @param vfHandler new {@link VirtualFileHandler}
+        */
+       public static
+       void
+       setVirtualFileHandler(
+               final VirtualFileHandler vfHandler
+       )
+       {
+               Connection.vfHandler = vfHandler;
+       }
+       
+       
+       
+       
+       /**
+        * Constructor with url
+        * 
+        * @param url {@link URL}
+        */
+       protected
+       Connection(
+               final URL url
+       )
+       {
+               super( url );
+               logger.trace( "URL :{}", url );
+       }
+
+       /* (non-Javadoc)
+        * @see java.net.URLConnection#connect()
+        */
+       @Override
+       public
+       void
+       connect()
+       throws IOException
+       {
+               logger.trace( "connect" );
+       }
+       
+       /* (non-Javadoc)
+        * @see java.net.URLConnection#getInputStream()
+        */
+       public
+       InputStream
+       getInputStream()
+       throws IOException
+       {
+               final String path = url.getPath();
+               logger.trace( "Path :{}", path );
+               return vfHandler.read( path );
+       }
+}
diff --git a/org.tizen.common/src/org/tizen/common/util/url/vf/Handler.java b/org.tizen.common/src/org/tizen/common/util/url/vf/Handler.java
new file mode 100644 (file)
index 0000000..95089ff
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+*  Common
+*
+* 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.common.util.url.vf;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+/**
+ * Handler.
+ * 
+ * {@link URLStreamHandler} for classpath url
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see org.tizen.common.util.url.classpath.Handler
+ */
+public class
+Handler
+extends URLStreamHandler
+{
+       /* (non-Javadoc)
+        * @see java.net.URLStreamHandler#openConnection(java.net.URL)
+        */
+       @Override
+       protected
+       URLConnection
+       openConnection(
+               final URL u
+       )
+       throws IOException
+       {
+               return new Connection( u );
+       }
+
+}
diff --git a/org.tizen.common/test/lib/asm-4.0.jar b/org.tizen.common/test/lib/asm-4.0.jar
new file mode 100644 (file)
index 0000000..6d63075
Binary files /dev/null and b/org.tizen.common/test/lib/asm-4.0.jar differ
diff --git a/org.tizen.common/test/lib/asm-tree-4.0.jar b/org.tizen.common/test/lib/asm-tree-4.0.jar
new file mode 100644 (file)
index 0000000..aa99d3a
Binary files /dev/null and b/org.tizen.common/test/lib/asm-tree-4.0.jar differ
diff --git a/org.tizen.common/test/lib/junit-4.10-src.jar b/org.tizen.common/test/lib/junit-4.10-src.jar
new file mode 100644 (file)
index 0000000..1449d28
Binary files /dev/null and b/org.tizen.common/test/lib/junit-4.10-src.jar differ
diff --git a/org.tizen.common/test/lib/junit-4.10.jar b/org.tizen.common/test/lib/junit-4.10.jar
new file mode 100644 (file)
index 0000000..bf5c0b9
Binary files /dev/null and b/org.tizen.common/test/lib/junit-4.10.jar differ
diff --git a/org.tizen.common/test/lib/mockito-all-1.9.0.jar b/org.tizen.common/test/lib/mockito-all-1.9.0.jar
new file mode 100644 (file)
index 0000000..273fd50
Binary files /dev/null and b/org.tizen.common/test/lib/mockito-all-1.9.0.jar differ
diff --git a/org.tizen.common/test/src/log4j.xml b/org.tizen.common/test/src/log4j.xml
new file mode 100755 (executable)
index 0000000..e5d1893
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+       <appender name="console" class="org.apache.log4j.ConsoleAppender">
+               <param name="Target" value="System.out" />
+               <layout class="org.apache.log4j.PatternLayout">
+                       <param name="ConversionPattern" value="[%p] %F(%L) - %m%n" />
+               </layout>
+       </appender>
+       
+       <root>
+               <priority value="info" />
+               <appender-ref ref="console" />
+       </root>
+</log4j:configuration>
\ No newline at end of file
diff --git a/org.tizen.common/test/src/org/tizen/common/AppIdGeneratorTest.java b/org.tizen.common/test/src/org/tizen/common/AppIdGeneratorTest.java
new file mode 100644 (file)
index 0000000..3481b7e
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact:
+* ChangHyun Lee <changhyun1.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.common;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * AppIdGeneratorTest.
+ *
+ * Test case for {@link AppIdGenerator}
+ *
+ * @author Changhyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *
+ * @see AppIdGenerator
+ *
+ */
+public class AppIdGeneratorTest {
+
+    /**
+     * Test {@link AppIdGenerator#generate()}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link AppIdGenerator#generate()}
+     */
+    @Test
+    public void test_generate() throws Exception {
+        AppIdGenerator generator = new AppIdGenerator();
+        String id = generator.generate();
+        String id2 = generator.generate();
+        assertTrue(id.length() == 10);
+        assertTrue(id2.length() == 10);
+    }
+
+    /**
+     * Test {@link AppIdGenerator#generate(int size)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link AppIdGenerator#generate(int size)}
+     */
+    @Test
+    public void test_generate2() throws Exception {
+        AppIdGenerator generator = new AppIdGenerator();
+        String id = generator.generate(10);
+        String id2 = generator.generate(11);
+        assertTrue(id.length() == 10);
+        assertTrue(id2.length() == 11);
+    }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/ClassSource.java b/org.tizen.common/test/src/org/tizen/common/ClassSource.java
new file mode 100644 (file)
index 0000000..6e4a9cc
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Common
+ *
+ * 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.common;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * <p>
+ * ClassSource.
+ * 
+ * Provide resource in class path
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public interface
+ClassSource
+{
+       /**
+        * Provide {@link InputStream} of resource having <code>path</code> besed on classpath 
+        * 
+        * @param path relative path based on classpath
+        * 
+        * @return {@link InputStream}
+        * 
+        * @throws IOException If resource can't be accessible
+        */
+       InputStream getResource( String path ) throws IOException;
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/CommonPluginTest.java b/org.tizen.common/test/src/org/tizen/common/CommonPluginTest.java
new file mode 100644 (file)
index 0000000..4082bfa
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+*  Common
+*
+* 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.common;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.tizen.common.FrequentlyUsedMatcher.doNotCare;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.junit.Test;
+import org.tizen.common.core.application.InstallPathConfig;
+import org.tizen.common.ui.page.preference.TizenBasePreferencePage;
+
+
+
+/**
+ * CommonPluginTest
+ *
+ * Test case for {@link CommonPlugin}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see CommonPlugin
+ */
+public class
+CommonPluginTest
+{
+       /**
+        * Test {@link CommonPlugin#initializeDefaultPreferences(IPreferenceStore)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see CommonPlugin#initializeDefaultPreferences(IPreferenceStore)
+        */
+       @Test
+       public void test_initializeDefaultPreferences() throws Exception
+       {
+               final CommonPlugin plugin = new CommonPlugin();
+               final IPreferenceStore preferenceStore = mock( IPreferenceStore.class );
+
+               plugin.initializeDefaultPreferences( preferenceStore );
+               
+               /*
+                * LookAtMe : Test with No argument specification
+                */
+               if ( null != InstallPathConfig.getSDKPath() )
+               {
+                       // in case of non-installed env.
+                       verify( preferenceStore ).setDefault(
+                               eq( TizenBasePreferencePage.KEY_SDKLOCATION ),
+                               (String) doNotCare()
+                       );
+               }
+               verify( preferenceStore ).setDefault( TizenBasePreferencePage.KEY_SDKUPDATE, true );
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/DirectorySource.java b/org.tizen.common/test/src/org/tizen/common/DirectorySource.java
new file mode 100644 (file)
index 0000000..172d9cc
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Common
+ *
+ * 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.common;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * <p>
+ * DirectorySource.
+ * 
+ * Directory base {@link ClassSource}
+ * 
+ * Provide *.class file as {@link InputStream}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+DirectorySource
+implements ClassSource
+{
+       /**
+        * Root directory
+        */
+       protected final File root;
+
+       /**
+        * Constructor with base directory path
+        * 
+        * @param root directory path
+        */
+       public
+       DirectorySource(
+               final String root
+       )
+       {
+               this.root = new File( root );
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.ClassSource#getResource(java.lang.String)
+        */
+       @Override
+       public
+       InputStream
+       getResource(
+               final String path
+       )
+       throws IOException
+       {
+               final File file = new File( root, path );
+
+               if ( file.exists() && file.canRead() )
+               {
+                       return new FileInputStream( file );
+               }
+               return null;
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/FrequentlyUsedMatcher.java b/org.tizen.common/test/src/org/tizen/common/FrequentlyUsedMatcher.java
new file mode 100644 (file)
index 0000000..01423c6
--- /dev/null
@@ -0,0 +1,70 @@
+package org.tizen.common;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.mockito.Matchers;
+
+public class FrequentlyUsedMatcher
+{
+       public static <T> T doNotCare()
+       {
+               return Matchers.argThat( new BaseMatcher<T>()
+               {
+                       public boolean matches( final Object arg )
+                       {
+                               return true;
+                       }
+                       
+                       public void describeTo( final Description desc )
+                       {
+                       }
+               } );
+       }
+       
+       public static <T> T eq( T type )
+       {
+               return Matchers.eq( type );
+       }
+
+       
+       public static boolean eq( boolean type )
+       {
+               return Matchers.eq( type );
+       }
+
+       public static byte eq( byte type )
+       {
+               return Matchers.eq( type );
+       }
+
+       public static char eq( char type )
+       {
+               return Matchers.eq( type );
+       }
+
+       public static double eq( double type )
+       {
+               return Matchers.eq( type );
+       }
+
+       public static float eq( float type )
+       {
+               return Matchers.eq( type );
+       }
+
+       public static int eq( int type )
+       {
+               return Matchers.eq( type );
+       }
+
+       public static long eq( long type )
+       {
+               return Matchers.eq( type );
+       }
+
+       public static short eq( short type )
+       {
+               return Matchers.eq( type );
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/JarSource.java b/org.tizen.common/test/src/org/tizen/common/JarSource.java
new file mode 100644 (file)
index 0000000..60033bd
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Common
+ *
+ * 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.common;
+
+import static org.tizen.common.util.IOUtil.getBytes;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * <p>
+ * JarSource.
+ * 
+ * Read jar file and provide class {@link InputStream}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+JarSource
+implements ClassSource
+{
+
+       /**
+        * Jar file path
+        */
+       protected final String path;
+
+       /**
+        * Constructor with jar file path
+        * 
+        * @param location jar path
+        */
+       public
+       JarSource(
+               String location
+       )
+       {
+               if ( null == location )
+               {
+                       throw new NullPointerException();
+               }
+               this.path = location;
+       }
+
+       /* (non-Javadoc)
+        * @see org.tizen.common.ClassSource#getResource(java.lang.String)
+        */
+       @Override
+       public
+       InputStream
+       getResource(
+               final String path
+       )
+       throws IOException
+       {
+               final JarFile file = new JarFile( new File( this.path ) );
+               final JarEntry entry = file.getJarEntry( path );
+               if ( null == entry )
+               {
+                       return null;
+               }
+               InputStream in = null;
+               try
+               {
+                       in = file.getInputStream( entry );
+                       ByteArrayInputStream byteIn = new ByteArrayInputStream( getBytes( in ) );
+                       return byteIn;
+               }
+               finally
+               {
+                       tryClose( in );
+                       file.close();
+               }
+       }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/Location.java b/org.tizen.common/test/src/org/tizen/common/Location.java
new file mode 100644 (file)
index 0000000..3a08e95
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Common
+ *
+ * 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.common;
+
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>
+ * Location.
+ * 
+ * Annotation for class path
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target({java.lang.annotation.ElementType.TYPE})
+@Inherited
+public @interface Location
+{
+       /**
+        * reeturn classpath
+        * 
+        * @return classpath
+        */
+       String[] value();
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/TestAgent.java b/org.tizen.common/test/src/org/tizen/common/TestAgent.java
new file mode 100644 (file)
index 0000000..f06d4ae
--- /dev/null
@@ -0,0 +1,17 @@
+package org.tizen.common;
+
+import java.lang.instrument.Instrumentation;
+
+public class
+TestAgent
+{
+       public static void premain(
+               final String name,
+               final Instrumentation inst
+       )
+       {
+               inst.addTransformer( new Transformer() );
+       }
+
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/Transformer.java b/org.tizen.common/test/src/org/tizen/common/Transformer.java
new file mode 100644 (file)
index 0000000..bbdefa3
--- /dev/null
@@ -0,0 +1,38 @@
+package org.tizen.common;
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.ClassNode;
+
+public class
+Transformer
+implements ClassFileTransformer
+{
+       @Override
+       public
+       byte[] transform(
+               final ClassLoader loader,
+               final String className,
+               final Class<?> classBeingRedefined,
+               final ProtectionDomain protectionDomain,
+               final byte[] bytes
+       )
+       throws IllegalClassFormatException
+       {
+               ClassReader      reader = new ClassReader( bytes );
+               ClassNode classNode = new ClassNode();
+               reader.accept( classNode, 0 );
+               classNode.access &= (~Opcodes.ACC_FINAL);
+
+               final ClassWriter cw =
+                       new ClassWriter( ClassWriter.COMPUTE_MAXS|ClassWriter.COMPUTE_FRAMES );
+               classNode.accept( cw );
+               return cw.toByteArray();
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/UnsafeClassLoader.java b/org.tizen.common/test/src/org/tizen/common/UnsafeClassLoader.java
new file mode 100644 (file)
index 0000000..dcf8d33
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * 
+ *
+ * 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.common;
+
+import static org.tizen.common.util.IOUtil.getBytes;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.util.IOUtil;
+
+
+/**
+ * <p>
+ * UnsafeClassLoader.
+ * 
+ * Classloader for untestable class
+ * 
+ * FIXME add {@link Package} info and {@link #getResource(String)}, {@link #getResourceAsStream(String)}, {@link #getResources(String)}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+UnsafeClassLoader
+extends ClassLoader
+{
+       /**
+        * Logger for this instance
+        */
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+       
+       /**
+        * Parent classloader
+        */
+       protected final ClassLoader parent;
+       
+       protected ClassFileTransformer transformer = new Transformer();
+
+       /**
+        * {@link ClassSource}s providing class contents
+        */
+       protected final ArrayList<ClassSource> sources = new ArrayList<ClassSource>();
+
+       /**
+        * Constructor with {@link ClassSource}s
+        * @param source
+        */
+       public
+       UnsafeClassLoader(
+               final ClassSource... source
+       )
+       {
+               this( null, source );
+       }
+
+       /**
+        * Constructor with parent class loader and class source
+        * 
+        * @param parent {@link ClassLoader}
+        * @param sources {@link ClassSource}s
+        */
+       public
+       UnsafeClassLoader(
+               final ClassLoader parent,
+               final ClassSource... sources
+       )
+       {
+               this.parent = parent;
+               this.sources.addAll( Arrays.asList( sources ) );
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+        */
+       @Override
+       synchronized protected
+       Class<?>
+       loadClass(
+               final String name,
+               final boolean resolve
+       )
+       throws ClassNotFoundException
+       {
+               // First, check if the class has already been loaded
+               Class<?> c = findLoadedClass( name );
+               if ( c == null )
+               {
+                       if ( name.startsWith( "java." ) )
+                       {
+                               return ClassLoader.getSystemClassLoader().loadClass( name );
+                       }
+                       try
+                       {
+                               c = findClass( name );
+                       } catch (ClassNotFoundException e) {
+                               if ( null != parent )
+                               {
+                                       c = parent.loadClass( name );
+                               }
+                               else
+                               {
+                                       throw new ClassNotFoundException();
+                               }
+                       }
+               }
+               if ( resolve )
+               {
+                       resolveClass( c );
+               }
+               return c;
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.ClassLoader#findClass(java.lang.String)
+        */
+       @Override
+       protected
+       Class<?>
+       findClass(
+               final String name
+       )
+       throws ClassNotFoundException
+       {
+               logger.trace( "Class name :{}", name );
+               final String path = name.replace( '.', '/' ) + ".class";
+               for ( final ClassSource source : sources )
+               {
+                       logger.trace( "Source :{}", source );
+                       InputStream in = null;;
+                       try
+                       {
+                               in = source.getResource( path );
+                               final Class<?> clazz = define( name, in );
+                               if ( null != clazz )
+                               {
+                                       return clazz;
+                               }
+                       }
+                       catch ( final IOException e )
+                       {
+                       }
+                       finally
+                       {
+                               tryClose( in );
+                       }
+               }
+               
+//             final ClassLoader loader = getClass().getClassLoader();
+//             
+//             final InputStream in = loader.getResourceAsStream( path );
+//             try
+//             {
+//                     final Class<?> clazz = define( name, in );
+//                     if ( null != clazz )
+//                     {
+//                             return clazz;
+//                     }
+//             }
+//             finally
+//             {
+//                     tryClose( in );
+//             }
+//
+               throw new ClassNotFoundException();
+
+       }
+       
+       protected Class<?> define(
+               final String name,
+               final InputStream in
+       )
+       {
+               try {
+                       if ( null == in )
+                       {
+                               return null;
+                       }
+                       byte[] bytes = getBytes( in );
+                       final String qn = name.replace( '.', '/' );
+                       bytes = transformer.transform( this, qn, null, null, bytes );
+                       logger.trace( "{} bytes read", bytes.length );
+                       return defineClass( name, bytes, 0, bytes.length );
+               } catch ( final IOException e )
+               {
+               } catch ( final IllegalClassFormatException e )
+               {
+               }
+               
+               return null;
+       }
+
+       /**
+        * Write log file about converted class
+        * 
+        * @param path file path to write
+        * @param bytes class contents
+        * 
+        * @throws IOException If file can't be write
+        */
+       protected
+       void
+       writeLog(
+               final String path,
+               byte[] bytes
+       )
+       throws IOException
+       {
+               FileOutputStream fileOut = null;
+               try
+               {
+                       File logFile = new File( "test/log/" + path );
+                       logFile.getParentFile().mkdirs();
+                       fileOut = new FileOutputStream( logFile );
+                       IOUtil.redirect( new ByteArrayInputStream( bytes ), fileOut );
+               }
+               finally
+               {
+                       tryClose( fileOut);
+               }
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/UnsafeRunner.java b/org.tizen.common/test/src/org/tizen/common/UnsafeRunner.java
new file mode 100644 (file)
index 0000000..dd17f9a
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * 
+ *
+ * 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.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.internal.builders.JUnit4Builder;
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.model.InitializationError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * UnsafeRunner.
+ * 
+ * JUnit extensible {@link Runner}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+UnsafeRunner
+extends ParentRunner<Runner>
+{
+       /**
+        * Logger for this instance
+        */
+       protected final Logger logger = LoggerFactory.getLogger( getClass() );
+
+       /**
+        * Classloader to convert test case
+        */
+       protected ClassLoader loader;
+
+       /**
+        * Test case name
+        */
+       protected final String className;
+
+       /**
+        * Constructor with test case {@link Class}
+        * 
+        * @param testClass test case {@link Class}
+        * 
+        * @throws InitializationError If <code>testClass</code> is invalid test case
+        */
+       public
+       UnsafeRunner(
+               final Class<?> testClass
+       )
+       throws InitializationError
+       {
+               super( testClass );
+               logger.trace( "Class :{}", testClass );
+
+               this.className = testClass.getName();
+
+               ClassSource[] sources = getSources( testClass );
+
+               loader = new UnsafeClassLoader( getClass().getClassLoader(), sources );
+       }
+
+       /**
+        * Extrace {@link ClassSource} from test case's annotation
+        * 
+        * @param testClass test case
+        * 
+        * @return {@link ClassSource}s
+        */
+       protected
+       ClassSource[] getSources(
+               final Class<?> testClass
+       )
+       {
+               final Location annotation =
+                       testClass.getAnnotation( Location.class );
+               if ( null == annotation )
+               {
+                       return new ClassSource[0];
+               }
+
+               final String[] locations = annotation.value();
+
+               final ArrayList<ClassSource> sources = new ArrayList<ClassSource>();
+
+               for ( final String location : locations )
+               {
+                       if ( location.endsWith( ".jar" ) )
+                       {
+                               sources.add( new JarSource( location ) );
+                       }
+                       else if ( location.endsWith( "/" ) )
+                       {
+                               sources.add( new DirectorySource( location ) );
+                       }
+               }
+
+               return sources.toArray( new ClassSource[0] );
+       }
+
+       /* (non-Javadoc)
+        * @see org.junit.runners.ParentRunner#getChildren()
+        */
+       @Override
+       protected
+       List<Runner>
+       getChildren()
+       {
+               final ArrayList<Runner> runners = new ArrayList<Runner>();
+               try {
+                       final Class<?> clazz = loader.loadClass( className );
+                       logger.trace( "Class :{}, Loader :{}", clazz, clazz.getClassLoader() );
+                       final JUnit4Builder builder = new JUnit4Builder();
+                       runners.add( builder.runnerForClass( clazz ) );
+               } catch (ClassNotFoundException e) {
+                       e.printStackTrace();
+               } catch (Throwable e) {
+                       e.printStackTrace();
+               }
+
+               logger.debug( "Runners :{}", runners );
+
+               return runners;
+       }
+
+       /* (non-Javadoc)
+        * @see org.junit.runners.ParentRunner#describeChild(java.lang.Object)
+        */
+       @Override
+       protected
+       Description
+       describeChild(
+               final Runner runner
+       )
+       {
+               return runner.getDescription();
+       }
+
+       /* (non-Javadoc)
+        * @see org.junit.runners.ParentRunner#runChild(java.lang.Object, org.junit.runner.notification.RunNotifier)
+        */
+       @Override
+       protected
+       void
+       runChild(
+               final Runner runner,
+               final RunNotifier notifier
+       )
+       {
+               logger.trace( "Runner :{}", runner );
+               runner.run( notifier );
+       }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/application/MessagesTest.java b/org.tizen.common/test/src/org/tizen/common/core/application/MessagesTest.java
new file mode 100644 (file)
index 0000000..85ea2c5
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+*  Common
+*
+* 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.common.core.application;
+
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+import org.tizen.common.util.StringUtil;
+
+
+/**
+ * MessagesTest
+ *
+ * Test case for {@link MessagesTest}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see MessagesTest
+ */
+public class MessagesTest
+{
+
+       /**
+        * Test {@link Messages}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Messages}
+        * @see Messages#DIALOG_TITLE
+        */
+       @Test
+       public void test_Messages() throws Exception
+       {
+               assertFalse( StringUtil.isEmpty( Messages.DIALOG_TITLE ) );
+       }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/application/StatusLineMessageManagerTest.java b/org.tizen.common/test/src/org/tizen/common/core/application/StatusLineMessageManagerTest.java
new file mode 100644 (file)
index 0000000..24e3374
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+*  Common
+*
+* 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.common.core.application;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.eclipse.jface.action.IStatusLineManager;
+import org.junit.Test;
+
+
+/**
+ * StatusLineMessageManagerTest
+ *
+ * Test case for {@link StatusLineMessageManager}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see StatusLineMessageManager
+ */
+public class StatusLineMessageManagerTest
+{
+       /**
+        * Test {@link StatusLineMessageManager#setMessage(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link StatusLineMessageManager#setMessage(String)}
+        */
+       @Test
+       public void test_setMessage() throws Exception
+       {
+               final String[] TEST_CASES = new String[] {
+                       null, "Hello", "Test"
+               };
+               
+               for ( final String TEST_CASE : TEST_CASES )
+               {
+                       final IStatusLineManager statusLineManager = mock( IStatusLineManager.class );
+                       final StatusLineMessageManager manager =
+                               new StatusLineMessageManager( statusLineManager );
+                       
+                       manager.setMessage( TEST_CASE );
+                       verify( statusLineManager ).setMessage( TEST_CASE );
+               }
+       }
+
+       /**
+        * Test {@link StatusLineMessageManager#setErrorMessage(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link StatusLineMessageManager#setErrorMessage(String)}
+        */
+       @Test
+       public void test_setErrorMessage() throws Exception
+       {
+               final String[] TEST_CASES = new String[] {
+                       null, "Hello", "Test"
+               };
+               
+               for ( final String TEST_CASE : TEST_CASES )
+               {
+                       final IStatusLineManager statusLineManager = mock( IStatusLineManager.class );
+                       final StatusLineMessageManager manager =
+                               new StatusLineMessageManager( statusLineManager );
+                       
+                       manager.setErrorMessage( TEST_CASE );
+                       verify( statusLineManager ).setErrorMessage( TEST_CASE );
+               }
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/CommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/CommandTest.java
new file mode 100755 (executable)
index 0000000..14d1864
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *  Common
+ *
+ * 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.common.core.command;
+
+import org.junit.After;
+import org.junit.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.common.core.command.policy.PolicyRegistry;
+import org.tizen.common.core.command.prompter.NopPrompter;
+import org.tizen.common.file.VirtualFileHandler;
+
+/**
+ * CommandTest
+ *
+ * Test case for {@link Command}'s sub class
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+CommandTest
+{
+    
+    /**
+     * Logger for testcase
+     */
+    protected final Logger logger = LoggerFactory.getLogger( getClass() );
+       /**
+        * {@link ExecutionContext} for test
+        */
+       protected ExecutionContext context;
+       
+       /**
+        * {@link Executor} for test
+        */
+       protected Executor executor;
+       
+       /**
+        * Return {@link Prompter} for test
+        * 
+        * @return {@link Prompter}
+        */
+       protected
+       Prompter
+       getPrompter()
+       {
+               return context.getPrompter();
+       }
+
+       /**
+        * Return {@link PolicyRegistry} for test
+        *  
+        * @return {@link PolicyRegistry}
+        */
+       protected
+       PolicyRegistry
+       getPolicies() {
+               return context.getPolicyRegistry();
+       }
+       
+       /**
+        * Return {@link VirtualFileHandler} for test
+        * 
+        * @return {@link VirtualFileHandler}
+        */
+       protected
+       VirtualFileHandler
+       getFileHandler()
+       {
+               return (VirtualFileHandler) context.getFileHandler();
+       }
+       
+       /**
+        * Return {@link Executor} for test
+        * 
+        * @return {@link Executor}
+        */
+       protected
+       Executor
+       getExecutor()
+       {
+               return this.executor;
+       }
+       
+       /**
+        * Return {@link ExecutionContext} for test
+        * 
+        * @return {@link ExecutionContext}
+        */
+       protected
+       ExecutionContext
+       getExecutionContext()
+       {
+               return this.context;
+       }
+       
+       /**
+        * Create prompter for test
+        * 
+        * @return {@link Prompter}
+        * 
+        * @see NopPrompter
+        */
+       protected
+       Prompter
+       createPrompter()
+       {
+               return new NopPrompter();
+       }
+       
+       /**
+        * Set up test
+        */
+       @Before
+       public void setUp()
+       {
+               context = new ExecutionContext( new PolicyRegistry(), createPrompter(), new VirtualFileHandler() );
+       }
+       
+       /**
+        * Tear down test
+        */
+       @After
+       public void tearDown()
+       {
+               context = null;
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/CompositeCommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/CompositeCommandTest.java
new file mode 100644 (file)
index 0000000..735763a
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Common
+ *
+ * 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.common.core.command;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.Test;
+
+
+/**
+ * CompositeCommandTest
+ *
+ * Test case for {@link CompositeCommand}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see CompositeCommandTest
+ */
+public class
+CompositeCommandTest
+extends CommandTest
+{
+       /**
+        * Test {@link CompositeCommand#execute(Executor, ExecutionContext)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see CompositeCommand#execute(Executor, ExecutionContext)
+        */
+       @Test
+       public
+       void
+       test_execute()
+       throws Exception
+       {
+               final AtomicInteger value = new AtomicInteger( 1 );
+               final AbstractCommand<Object> command1 = new AbstractCommand<Object>()
+               {
+                       
+                       /* (non-Javadoc)
+                        * @see org.tizen.common.core.command.AbstractCommand#run(org.tizen.common.core.command.Executor, org.tizen.common.core.command.ExecutionContext)
+                        */
+                       @Override
+                       public
+                       void
+                       run(
+                               final Executor executor,
+                               final ExecutionContext context
+                       )
+                       throws Exception
+                       {
+                               value.set( value.get() + 1 );
+                       }
+               };
+               final AbstractCommand<Object> command2 = new AbstractCommand<Object>()
+               {
+                       
+                       /* (non-Javadoc)
+                        * @see org.tizen.common.core.command.AbstractCommand#run(org.tizen.common.core.command.Executor, org.tizen.common.core.command.ExecutionContext)
+                        */
+                       @Override
+                       public
+                       void
+                       run(
+                               final Executor executor,
+                               final ExecutionContext context
+                       )
+                       throws Exception
+                       {
+                               value.set( value.get() * 3 );
+                       }
+               };
+               
+               final CompositeCommand commands = new CompositeCommand( command1, command2 );
+               commands.run( getExecutor(), getExecutionContext() );
+               
+               assertEquals( 6, value.get() );
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/ExecutionContextTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/ExecutionContextTest.java
new file mode 100644 (file)
index 0000000..5be95d5
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Common
+ *
+ * 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.common.core.command;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.tizen.common.core.command.policy.PolicyRegistry;
+import org.tizen.common.core.command.prompter.NopPrompter;
+import org.tizen.common.file.VirtualFileHandler;
+
+
+/**
+ * ExecutionContextTest
+ *
+ * Test case for {@link ExecutionContext}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see ExecutionContext
+ */
+public class
+ExecutionContextTest
+{
+       /**
+        * Test {@link ExecutionContext#getPolicyRegistry()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see ExecutionContext#getPolicyRegistry()
+        */
+       @Test
+       public void test_getPolicyRegistry() throws Exception {
+               // Given
+               final PolicyRegistry registry = new PolicyRegistry();
+               final ExecutionContext context = new ExecutionContext( registry, null, null );
+               
+               // When & Then
+               assertEquals( registry, context.getPolicyRegistry() );
+       }
+       
+       /**
+        * Test {@link ExecutionContext#getPrompter()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see ExecutionContext#getPrompter()
+        */
+       @Test
+       public void test_getPrompter() throws Exception {
+               // Given
+               final NopPrompter prompter = new NopPrompter();
+               final ExecutionContext context = new ExecutionContext( null, prompter, null );
+               
+               // When & Then
+               assertEquals( prompter, context.getPrompter() );
+               
+       }
+       
+       /**
+        * Test {@link ExecutionContext#getFileHandler()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see ExecutionContext#getFileHandler()
+        */
+       @Test
+       public void test_getFileHandler() throws Exception {
+               // Given
+               final VirtualFileHandler handler = new VirtualFileHandler();
+               final ExecutionContext context = new ExecutionContext( null, null, handler );
+               
+               // When & Then
+               assertEquals( handler, context.getFileHandler() );
+       }
+       
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/file/FileHandlingCommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/file/FileHandlingCommandTest.java
new file mode 100644 (file)
index 0000000..b1bcb6e
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.file;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.tizen.common.file.Filter;
+import org.tizen.common.file.SimpleFileFilter;
+
+
+/**
+ * FileHandlingCommandTest.
+ *
+ * Test case for {@link FileHandlingCommand}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see FileHandlingCommand
+ */
+public class
+FileHandlingCommandTest
+{
+       
+       /**
+        * Test {@link FileHandlingCommand#setFilter(SimpleFileFilter)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see FileHandlingCommand#setFilter(SimpleFileFilter)
+        */
+       @Test
+       public
+       void
+       test_setFilter() throws Exception
+       {
+               // Given
+               final FileHandlingCommand<Object> command = new FileHandlingCommand<Object>();
+               
+               // When & Then
+               command.setFilter( new SimpleFileFilter() );
+               
+               try
+               {
+                       // When
+                       command.setFilter( null );
+                       fail();
+               }
+               catch ( NullPointerException e )
+               {
+                       // Then
+               }
+       }
+       
+       /**
+        * Test {@link FileHandlingCommand#setIncludes(String[])}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see FileHandlingCommand#setIncludes(String[])
+        */
+       @Test
+       public void test_setIncludes() throws Exception {
+               // Given
+               final FileHandlingCommand<Object> command = new FileHandlingCommand<Object>();
+               SimpleFileFilter mockFilter = mock( SimpleFileFilter.class );
+               command.setFilter( mockFilter );
+               
+               // When
+               command.setIncludes( new String[] { "*" } );
+               
+               // Then
+               verify( mockFilter ).clearIncludes();
+               verify( mockFilter ).addIncludes( Matchers.<Filter>any() );
+               
+       }
+       
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/policy/PolicyRegistryTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/policy/PolicyRegistryTest.java
new file mode 100644 (file)
index 0000000..b6f88ea
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.policy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+
+
+/**
+ * PolicyRegistryTest
+ *
+ * Test case for {@link PolicyRegistry}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see PolicyRegistry
+ */
+public class PolicyRegistryTest
+{
+
+       /**
+        * Test {@link PolicyRegistry#getPolicy(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see PolicyRegistry#getPolicy(String)
+        */
+       @Test
+       public void test_getPolicy() throws Exception {
+               final PolicyRegistry register = new PolicyRegistry();
+               
+               final AbstractPolicy expected = new AbstractPolicy( "exist.output.file" ) {
+                       public <T> T adapt(Class<T> clazz) {
+                               return null;
+                       }
+               };
+               
+               register.register( expected );
+               
+               assertNotNull( register.getPolicy( null ) );
+               assertNotNull( register.getPolicy( "" ) );
+               assertEquals( null, register.getPolicy( "exist" ) );
+               assertEquals( null, register.getPolicy( "exist.output" ) );
+               assertEquals( expected, register.getPolicy( "exist.output.file.xml" ) );
+               assertEquals( expected, register.getPolicy( "exist.output.file" ) );
+       }
+       
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/prompter/GenericOptionTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/prompter/GenericOptionTest.java
new file mode 100644 (file)
index 0000000..4094c3e
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+
+/**
+ * <p>
+ * GenericOptionTest.
+ * 
+ * Test case for {@link GenericOption}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see GenericOption
+ */
+public class
+GenericOptionTest
+{
+       /**
+        * Test {@link GenericOption#isMatch(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see GenericOption#isMatch(String)
+        */
+       @Test
+       public
+       void
+       test_isMatch()
+       throws Exception
+       {
+
+               final GenericOption option = new GenericOption();
+
+               assertTrue( option.isMatch( "Hello" ) );
+               assertTrue( option.isMatch( "World" ) );
+
+
+       }
+
+       /**
+        * Test {@link GenericOption#getAnswer()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see GenericOption#getAnswer()
+        */
+       @Test
+       public
+       void
+       test_getAnswer()
+       throws Exception
+       {
+               final String userAnser = "Dummy answer";
+               NopPrompter prompter = new NopPrompter() {
+                       @Override
+                       public Option interact(String question, Option... options) {
+                               options[0].isMatch( userAnser );
+                               return options[0];
+                       }
+               };
+               GenericOption option = new GenericOption();
+               final Option answer = prompter.interact( "Answer ?", option );
+               
+               assertEquals( userAnser, ((GenericOption) answer).getAnswer() );
+               assertEquals( userAnser, answer.toString() );
+               
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/prompter/OptionTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/prompter/OptionTest.java
new file mode 100644 (file)
index 0000000..beb2027
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+
+/**
+ * OptionTest
+ * 
+ * Test case for {@link ChoiceOption}
+ * 
+ * @author bylee
+ *
+ * @see ChoiceOption
+ */
+public class
+OptionTest
+{
+       /**
+        * Test {@link ChoiceOption#isMatch(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see ChoiceOption#isMatch(String)
+        */
+       @Test
+       public
+       void
+       test_isMatch()
+       throws Exception
+       {
+               // Test cases
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] {
+                               new ChoiceOption( "test" ),
+                               new Object[][] {
+                                       new Object[] { "t", true },
+                                       new Object[] { "TEST", true },
+                                       new Object[] { "TEst", true },
+                                       new Object[] { "No", false },
+                                       new Object[] { null, false }
+                               }
+                       }
+               };
+               // Given
+               
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       
+                       final ChoiceOption option = (ChoiceOption) TEST_CASE[0];
+                       final Object[][] TEST_CASE2 = (Object[][]) TEST_CASE[1];
+                       for ( final Object[] TEST_CASE3 : TEST_CASE2 )
+                       {
+                               // When
+                               String input = (String) TEST_CASE3[0];
+                               boolean expected = (Boolean) TEST_CASE3[1];
+
+                               boolean result = option.isMatch( input );
+                               
+                               // Then
+                               assertEquals( expected, result );
+                       }
+               }
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/prompter/SWTPrompterTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/prompter/SWTPrompterTest.java
new file mode 100644 (file)
index 0000000..f222f83
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Common
+ *
+ * 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.common.core.command.prompter;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.junit.Test;
+
+
+/**
+ * SWTPrompterTest
+ *
+ * Test case for {@link SWTPrompter}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see SWTPrompter
+ */
+public class
+SWTPrompterTest
+{
+       /**
+        * Test {@link SWTPrompter#interact(String, ChoiceOption...)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see SWTPrompter#interact(String, ChoiceOption...)
+        */
+       @Test
+       public void test_interact() throws Exception {
+               {
+                       // Given
+                       final MessageDialog mockDialog = mock( MessageDialog.class );
+                       when( mockDialog.getReturnCode() ).thenReturn( 0 );
+                       final SWTPrompter prompter = new SWTPrompter() {
+                               @Override
+                               protected Dialog createDialog(
+                                       final String question,
+                                       final String[] optionNames,
+                                       final int defaultOptionIndex
+                               )
+                               {
+                                       return mockDialog;
+                               }
+                       };
+                       
+                       // When
+                       ChoiceOption opt1 = new ChoiceOption( "Yes" );
+                       ChoiceOption opt2 = new ChoiceOption( "No", true );
+                       
+                       // Then
+                       Option result = prompter.interact( "Yes or No", opt1, opt2 );
+                       assertEquals( opt1, result );
+               }
+               
+               {
+                       // Given
+                       final MessageDialog mockDialog = mock( MessageDialog.class );
+                       when( mockDialog.getReturnCode() ).thenReturn( 1 );
+                       final SWTPrompter prompter = new SWTPrompter() {
+                               @Override
+                               protected Dialog createDialog(
+                                       final String question,
+                                       final String[] optionNames,
+                                       final int defaultOptionIndex
+                               )
+                               {
+                                       return mockDialog;
+                               }
+                       };
+                       
+                       // When
+                       ChoiceOption opt1 = new ChoiceOption( "Yes" );
+                       ChoiceOption opt2 = new ChoiceOption( "No", true );
+                       
+                       // Then
+                       Option result = prompter.interact( "Yes or No", opt1, opt2 );
+                       assertEquals( opt2, result );
+
+               }
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/sdb/DevicesSdbCommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/sdb/DevicesSdbCommandTest.java
new file mode 100644 (file)
index 0000000..205e8b0
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+import org.tizen.common.core.command.CommandTest;
+import org.tizen.sdblib.IDevice;
+
+/**
+ * DevicesSdbCommandTest
+ * 
+ * Test case for {@link DevicesSdbCommand}
+ * 
+ * @author GyeongSeok Seo{@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ *
+ * @see DevicesSdbCommand
+ */
+public class
+DevicesSdbCommandTest
+extends CommandTest
+{
+    @Test
+    public void test_execute() throws Exception {
+        DevicesSdbCommand testCommand = new DevicesSdbCommand() {
+            @Override
+            protected SmartDevelopmentBridgeManager createBridge() {
+                SmartDevelopmentBridgeManager mockBridge = mock( SmartDevelopmentBridgeManager.class );
+                IDevice mockDevice1 = mock( IDevice.class );
+                IDevice mockDevice2 = mock( IDevice.class );
+                when( mockDevice1.toString() ).thenReturn( "TizenDevice1" );
+                when( mockDevice2.toString() ).thenReturn( "TizenDevice2" );
+                when( mockBridge.getDevices() ).thenReturn( new IDevice[] { mockDevice1, mockDevice2 } );
+                return mockBridge;
+            }
+            
+        };
+        testCommand.run( null, context );
+        String result = "TizenDevice1" + System.getProperty("line.separator") + "TizenDevice2" + System.getProperty("line.separator");
+        assertEquals( result, testCommand.getResult() );
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/sdb/DlogSdbCommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/sdb/DlogSdbCommandTest.java
new file mode 100644 (file)
index 0000000..b8dcbe1
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import static org.junit.Assert.*;
+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;
+
+/**
+ * DlogSdbCommandTest
+ *
+ * Test case for {@link DlogSdbCommand}
+ * 
+ * @author GyeongSeok Seo{@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ * 
+ * @see DlogSdbCommand
+ */
+public class
+DlogSdbCommandTest
+extends CommandTest
+{
+    @Test
+    public void test_execute() throws Exception {
+        final MultiLineReceiver mockMultiLineReceiver = mock( MultiLineReceiver.class );
+        String cmd = "dlogutil";
+        DlogSdbCommand testCommand = new DlogSdbCommand() {
+            @Override
+            public MultiLineReceiver createMultiLineReceiver() {
+                return mockMultiLineReceiver;
+            }
+        };
+
+        try {
+            testCommand.run( null, context );
+            fail( "when device is null then must throw exception" );
+        } catch ( Exception e) {
+        }
+
+        IDevice mockDevice = mock( IDevice.class );
+        testCommand.setDevice( mockDevice );
+        try {
+            testCommand.run( null, context );
+            assertEquals( testCommand.getCommand(), cmd );
+            verify( mockDevice ).executeShellCommand( cmd, mockMultiLineReceiver );
+
+            testCommand.setFilter( "filter" );
+            testCommand.run( null, context );
+            assertEquals( testCommand.getCommand(), cmd + " filter" );
+            verify( mockDevice ).executeShellCommand( cmd + " filter", mockMultiLineReceiver );
+        } catch (Exception e) {
+            fail( "should't throw exception" );
+        }
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/sdb/ForwardSdbCommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/sdb/ForwardSdbCommandTest.java
new file mode 100644 (file)
index 0000000..30ba8d2
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import static org.junit.Assert.*;
+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;
+
+/**
+ * ForwardSdbCommandTest
+ *
+ * Test case for {@link ForwardSdbCommand}
+ * 
+ * @author GyeongSeok Seo{@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ * 
+ * @see ForwardSdbCommand
+ */
+public class
+ForwardSdbCommandTest
+extends CommandTest
+{
+    @Test
+    public void test_execute() throws Exception {
+        int localPort = 5000;
+        int remotePort = 4000;
+        ForwardSdbCommand testCommand = new ForwardSdbCommand(localPort, remotePort);
+
+        // device null test
+        try {
+            testCommand.run( null, context );
+            fail( "when device is null then must throw exception" );
+        } catch (Exception e) {
+        }
+
+        try {
+            IDevice mockDevice = mock( IDevice.class );
+            testCommand.setDevice( mockDevice );
+            testCommand.run( null, context );
+            verify( mockDevice ).createForward( localPort, remotePort );
+        } catch (Exception e) {
+            fail( "should't throw exception" );
+        }
+    }
+
+    @Test
+    public void test_undo() throws Exception {
+        int localPort = 5000;
+        int remotePort = 4000;
+        ForwardSdbCommand testCommand = new ForwardSdbCommand(localPort, remotePort);
+
+        // device null test
+        try {
+            testCommand.undo( null, context );
+            fail( "when device is null then must throw exception" );
+        } catch (Exception e) {
+        }
+
+        try {
+            IDevice mockDevice = mock( IDevice.class );
+            testCommand.setDevice( mockDevice );
+            testCommand.undo( null, context );
+            verify( mockDevice ).removeForward( localPort, remotePort );
+        } catch (Exception e) {
+            fail( "should't throw exception" );
+        }
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/sdb/PullSdbCommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/sdb/PullSdbCommandTest.java
new file mode 100644 (file)
index 0000000..7da5260
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.tizen.common.Location;
+import org.tizen.common.UnsafeRunner;
+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;
+
+/**
+ * PullSdbCommandTest
+ *
+ * Test case for {@link PullSdbCommand}
+ * 
+ * @author GyeongSeok Seo{@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ * 
+ * @see PullSdbCommand
+ */
+@RunWith( UnsafeRunner.class )
+@Location( { "lib/sdblib.jar", "bin/" } )
+public class
+PullSdbCommandTest
+extends CommandTest
+{
+    @Test
+    public void test_execute() throws Exception {
+        final IDevice mockDevice = mock( IDevice.class );
+        final SyncService mockService = mock( SyncService.class );
+        SyncResult r = mock( SyncResult.class );
+        when( mockService.pullFile( "remotePath", "localPath", SyncService.getNullProgressMonitor() ) )
+        .thenReturn( r );
+
+        PullSdbCommand testCommand = new PullSdbCommand( "remotePath", "localPath" )
+        {
+            @Override
+            protected SyncService getSyncService() throws TimeoutException,
+                    SdbCommandRejectedException, IOException {
+                return mockService;
+            }
+        };
+        testCommand.setDevice( mockDevice );
+        testCommand.run( null, context );
+    }
+
+    @Override
+    public String toString() {
+       return getClass().getSimpleName() + ":" + getClass().getClassLoader();
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/sdb/PushSdbCommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/sdb/PushSdbCommandTest.java
new file mode 100644 (file)
index 0000000..f37820f
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import static org.mockito.Mockito.mock;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+
+import org.junit.Test;
+import org.tizen.common.core.command.CommandTest;
+import org.tizen.sdblib.IDevice;
+import org.tizen.sdblib.SdbCommandRejectedException;
+import org.tizen.sdblib.SyncService;
+import org.tizen.sdblib.TimeoutException;
+
+/**
+ * PushSdbCommandTest
+ *
+ * Test case for {@link PushSdbCommand}
+ * 
+ * @author GyeongSeok Seo{@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ * 
+ * @see PushSdbCommand
+ */
+public class
+PushSdbCommandTest
+extends CommandTest
+{
+    @Test
+    public void test_execute() throws Exception {
+        IDevice mockDevice = mock( IDevice.class );
+        Class<?> serviceClass = SyncService.class;
+        Constructor<?>[] con = serviceClass.getDeclaredConstructors();
+        con[0].setAccessible( true );
+        final SyncService mockService = (SyncService) con[0].newInstance( null, null );
+
+        PushSdbCommand testCommand = new PushSdbCommand( "sourcePath", "targetPath" ) {
+            @Override
+            protected SyncService getSyncService() throws TimeoutException,
+                    SdbCommandRejectedException, IOException {
+                return mockService;
+            }
+        };
+        testCommand.setDevice( mockDevice );
+        testCommand.run( null, context );
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/sdb/ShellSdbCommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/sdb/ShellSdbCommandTest.java
new file mode 100644 (file)
index 0000000..db72653
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* GyeongSeok Seo <gyeongseok.seo@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.common.core.command.sdb;
+
+import static org.junit.Assert.*;
+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;
+
+/**
+ * ShellSdbCommandTest
+ *
+ * Test case for {@link ShellSdbCommand}
+ * 
+ * @author GyeongSeok Seo{@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ * 
+ * @see ShellSdbCommand
+ */
+
+public class
+ShellSdbCommandTest
+extends CommandTest
+{
+    @Test
+    public void test_execute() throws Exception {
+        String cmd = "ls";
+        final MultiLineReceiver mockMultiLineReceiver = mock( MultiLineReceiver.class );
+        ShellSdbCommand testCommand1 = new ShellSdbCommand();
+        ShellSdbCommand testCommand2 = new ShellSdbCommand( cmd ) {
+            @Override
+            public MultiLineReceiver createMultiLineReceiver() {
+                return mockMultiLineReceiver;
+            }
+            
+        };
+
+        // construction test
+        assertEquals( testCommand1.getCommand(), null );
+        assertEquals( testCommand2.getCommand(), cmd);
+
+        // time value test
+        assertEquals( testCommand1.getTime(), 90 );
+        testCommand1.setTime( 30 );
+        assertEquals( testCommand1.getTime(), 30 );
+        testCommand1.setTime( 1 );
+        assertEquals( testCommand1.getTime(), 1 );
+        testCommand1.setTime( 0 );
+        assertEquals( testCommand1.getTime(), 90 );
+        testCommand1.setTime( -1 );
+        assertEquals( testCommand1.getTime(), 90 );
+
+        try {
+            // device null test
+            testCommand1.run( null, context );
+            fail( "when device is null then must throw exception" );
+        } catch (Exception e) {
+        }
+
+        IDevice mockDevice = mock( IDevice.class );
+        testCommand1.setDevice( mockDevice );
+        testCommand2.setDevice( mockDevice );
+        try {
+            // command null test
+            testCommand1.run( null, context );
+            fail( "when command is null then must throw exception" );
+        } catch (Exception e) {
+        }
+
+        try {
+            // normal operation test
+            String clearResult =  "Test clearResult call";
+            testCommand2.setResult( clearResult );
+            testCommand2.run( null, context );
+
+            // clearResult call test
+            assertNotSame( clearResult, testCommand2.getResult() );
+            // executeShellCommand call test
+            verify( mockDevice ).executeShellCommand( cmd, mockMultiLineReceiver, 90000 );
+        } catch (Exception e) {
+            fail( "should't throw exception" );
+        }
+    }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/core/command/zip/ZipCommandTest.java b/org.tizen.common/test/src/org/tizen/common/core/command/zip/ZipCommandTest.java
new file mode 100644 (file)
index 0000000..a325eda
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  Common
+ *
+ * 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.common.core.command.zip;
+
+import static org.junit.Assert.assertTrue;
+import static org.tizen.common.util.ArrayUtil.size;
+import static org.tizen.common.util.IOUtil.getBytes;
+
+import java.io.InputStream;
+
+import org.junit.Test;
+import org.tizen.common.core.command.CommandTest;
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.file.FileHandler.Attribute;
+import org.tizen.common.file.VirtualFileHandler;
+
+
+/**
+ * ZipCommandTest
+ *
+ * Test case for {@link ZipCommand}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see ZipCommand
+ */
+public class
+ZipCommandTest
+extends CommandTest
+{
+       /**
+        * Test {@link ZipCommand#execute(Executor, ExecutionContext)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see ZipCommand#execute(Executor, ExecutionContext)
+        */
+       @Test
+       public void test_execute() throws Exception {
+               // Given
+               final VirtualFileHandler vfs = (VirtualFileHandler) context.getFileHandler();
+               vfs.makeDirectory( "/test" );
+               vfs.write( "/test/a.txt", "Hello, World" );
+               
+               // When
+               final ZipCommand command = new ZipCommand( "/test", "/test.zip" );
+               command.run( getExecutor(), getExecutionContext() );
+               
+               // Then
+               assertTrue( (Boolean) vfs.get( "/test.zip", Attribute.EXISTS ) );
+               final InputStream in = vfs.read( "/test.zip" );
+               assertTrue( 0 < size( getBytes( in, true ) ) );
+               
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/file/SimpleFileFilterTest.java b/org.tizen.common/test/src/org/tizen/common/file/SimpleFileFilterTest.java
new file mode 100755 (executable)
index 0000000..cb61e5c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.tizen.common.file.filter.WildCardFilter;
+
+
+/**
+ * <p>
+ * SimpleFileFilterTest.
+ *
+ * Test case for {@link SimpleFileFilter}
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see SimpleFileFilter
+ */
+public class
+SimpleFileFilterTest
+{
+       /**
+        * Test {@link SimpleFileFilter#accept(String, String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see SimpleFileFilter#accept(String, String)
+        */
+       @Test
+       public
+       void
+       test_accept()
+       throws Exception
+       {
+               SimpleFileFilter filter = new SimpleFileFilter();
+               filter.addIncludes( new WildCardFilter( "Test*" ) );
+               assertTrue( filter.accept( null, "/test/Test.txt" ) );
+               assertFalse( filter.accept( null, "/test/Te.txt" ) );
+               
+               filter.addExcludes( new WildCardFilter( "T*" ) );
+               assertFalse( filter.accept( null, "/test/Test.txt" ) );
+               
+               try
+               {
+                       filter.accept( null, "xxx.txt" );
+                       fail();
+               } catch ( final Exception e )
+               {
+               }
+               
+               filter.clearIncludes();
+               filter.setExcludes( new WildCardFilter( ".*" ), new WildCardFilter( "*~" ) );
+               assertTrue( filter.accept( null, "a.a.a." ) );
+               assertFalse( filter.accept( null, ".aaa." ) );
+               assertTrue( filter.accept( null, "~a~a~a~." ) );
+               assertFalse( filter.accept( null, "~a~a~a~" ) );
+               assertFalse( filter.accept( null, ".project" ) );
+               assertFalse( filter.accept( null, ".classpath" ) );
+               assertFalse( filter.accept( null, "viclone.txt~" ) );
+               
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/file/VirtualFileHandlerTest.java b/org.tizen.common/test/src/org/tizen/common/file/VirtualFileHandlerTest.java
new file mode 100644 (file)
index 0000000..d61fd69
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Common
+ *
+ * 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.common.file;
+
+import static org.junit.Assert.assertTrue;
+import static org.tizen.common.util.ArrayUtil.size;
+import static org.tizen.common.util.IOUtil.getBytes;
+
+import org.junit.Test;
+
+
+/**
+ * <p>
+ * VirtualFileHandlerTest.
+ * 
+ * Test case for {@link VirtualFileHandler}
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see VirtualFileHandler
+ */
+public class
+VirtualFileHandlerTest
+{
+       /**
+        * Test {@link VirtualFileHandler#write(String, String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see VirtualFileHandler#write(String, String)
+        */
+       @Test
+       public
+       void
+       test_write()
+       throws Exception
+       {
+               final VirtualFileHandler vfs = new VirtualFileHandler();
+
+               vfs.makeDirectory( "/test" );
+
+               vfs.write( "/test/a.txt", "Hello, World" );
+
+               assertTrue( 0 < size( getBytes( vfs.read( "/test/a.txt" ) ) ) );
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/file/filter/WildCardFilterFactoryTest.java b/org.tizen.common/test/src/org/tizen/common/file/filter/WildCardFilterFactoryTest.java
new file mode 100644 (file)
index 0000000..0bb5f3b
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Common
+ *
+ * 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.common.file.filter;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+
+/**
+ * <p>
+ * WildCardFilterFactoryTest.
+ * 
+ * Test case for {@link WildCardFilterFactory}
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see WildCardFilterFactory
+ */
+public class
+WildCardFilterFactoryTest
+{
+
+       /**
+        * Test {@link WildCardFilterFactory#create(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see WildCardFilterFactory#create(String)
+        */
+       @Test
+       public
+       void
+       test_create()
+       throws Exception
+       {
+               final WildCardFilterFactory factory = new WildCardFilterFactory();
+               
+               assertNotNull( factory.create( "*" ) );
+               assertNotNull( factory.create( "**" ) );
+               assertNotNull( factory.create( "?" ) );
+               assertNotNull( factory.create( "Test" ) );
+               assertNotNull( factory.create( "" ) );
+               try
+               {
+                       factory.create( null );
+                       fail();
+               }
+               catch ( NullPointerException e )
+               {
+               }
+               
+               
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/file/filter/WildCardFilterTest.java b/org.tizen.common/test/src/org/tizen/common/file/filter/WildCardFilterTest.java
new file mode 100644 (file)
index 0000000..b5477a2
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Common
+ *
+ * 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.common.file.filter;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+
+/**
+ * <p>
+ * WildCardFilterTest.
+ * 
+ * Test case for {@link WildCardFilter}
+ *
+ * </p>
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see WildCardFilter
+ */
+public class
+WildCardFilterTest
+{
+       /**
+        * Test {@link WildCardFilter#accept(String, String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see WildCardFilter#accept(String, String)
+        */
+       @Test
+       public void
+       test_accept()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { "aaa*", "aaaa/abc.text", false },
+                       new Object[] { "aaa*", "aaaa/aaa.text", true },
+                       new Object[] { "aaa*", "aaaa/aaa33.text", true },
+                       new Object[] { "aaa*", "aaaa/aa", false },
+                       new Object[] { ".*", ".text", true },
+                       new Object[] { "*Test*", "A_Test", true },
+               };
+
+
+               int iCase = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       ++iCase;
+
+                       final String pattern = (String) TEST_CASE[0];
+                       final String path = (String) TEST_CASE[1];
+                       final boolean expected = (Boolean) TEST_CASE[2];
+
+                       // Given
+                       
+                       // When
+                       final WildCardFilter filter = new WildCardFilter();
+                       filter.setPattern( pattern );
+                       
+                       // Then
+                       assertEquals( expected, filter.accept( "/", path ) );
+
+               }
+       }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/ui/page/preference/MessagesTest.java b/org.tizen.common/test/src/org/tizen/common/ui/page/preference/MessagesTest.java
new file mode 100644 (file)
index 0000000..7b56ab2
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+*  Common
+*
+* 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.common.ui.page.preference;
+
+import static org.junit.Assert.assertFalse;
+
+import org.junit.Test;
+import org.tizen.common.util.StringUtil;
+
+
+/**
+ * MessagesTest
+ *
+ * Test case for {@link MessagesTest}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see MessagesTest
+ */
+public class MessagesTest
+{
+       /**
+        * Test {@link Messages}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Messages}
+        * @see Messages#DESCRIPTION
+        * @see Messages#GROUP1
+        * @see Messages#GROUP2
+        * @see Messages#LABEL_LOCATION
+        * @see Messages#LABEL_UPDATE
+        */
+       @Test
+       public void test_Messages() throws Exception
+       {
+               assertFalse( StringUtil.isEmpty( Messages.DESCRIPTION ) );
+               assertFalse( StringUtil.isEmpty( Messages.GROUP1 ) );
+               assertFalse( StringUtil.isEmpty( Messages.GROUP2 ) );
+               assertFalse( StringUtil.isEmpty( Messages.LABEL_LOCATION ) );
+               assertFalse( StringUtil.isEmpty( Messages.LABEL_UPDATE ) );
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/ui/page/wizard/TrayWizardPageTest.java b/org.tizen.common/test/src/org/tizen/common/ui/page/wizard/TrayWizardPageTest.java
new file mode 100644 (file)
index 0000000..15a5609
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+*  Common
+*
+* 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.common.ui.page.wizard;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Composite;
+import org.junit.Test;
+import org.tizen.common.ui.dialog.ClosableTray;
+
+
+/**
+ * TrayWizardPageTest
+ *
+ * Test case for {@link TrayWizardPage}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see TrayWizardPage
+ */
+public class
+TrayWizardPageTest
+{
+       public void test_TrayWizardPage() throws Exception
+       {
+               assertEquals( "Test Page", (new TrayWizardPage( "Test Page" ) {
+                       public void createControl(Composite parent)
+                       {
+                       }
+               }).getName() );
+               
+               assertEquals( "Title", (new TrayWizardPage( "Test Page", "Title", null ) {
+                       public void createControl(Composite parent)
+                       {
+                       }
+               }).getTitle() );
+       }
+       @Test
+       public
+       void
+       test_openClosableTray()
+       throws Exception
+       {
+               final TrayWizardPage page = new TrayWizardPage( "Test Page" )
+               {
+                       public void createControl(Composite parent)
+                       {
+                       }
+               };
+
+               /*
+                * This means that functional is successful If run on WizardDialog
+                */
+               final IWizard wizard = mock( IWizard.class );
+               final WizardDialog dialog = mock( WizardDialog.class );
+               when( wizard.getContainer() ).thenReturn( dialog );
+               final ClosableTray tray = mock( ClosableTray.class );
+               
+               page.setWizard( wizard );
+               page.openClosableTray( tray );
+               
+               verify( dialog ).openTray( tray );
+       }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/ArrayUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/ArrayUtilTest.java
new file mode 100755 (executable)
index 0000000..863a1b7
--- /dev/null
@@ -0,0 +1,765 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* BonYong Lee <bonyong.lee@samsung.com>
+* Gun Kim <gune.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.common.util;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.tizen.common.util.ArrayUtil.safe;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+
+import org.junit.Test;
+
+
+/**
+ * ArrayUtilsTest
+ *
+ * Test case for {@link ArrayUtil}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see ArrayUtil
+ */
+public class ArrayUtilTest
+{
+    public static int arrayIndex = 0;
+    public static boolean successTest = true;
+
+    /**
+     * Test {@link ArrayUtil#pickupFirst(Collection)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ArrayUtil#pickupFirst(Collection)
+     */
+    @Test
+    public void
+    test_pickupFirst()
+            throws Exception
+            {
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null, null },
+                new Object[] { new Object[] { null }, null },
+                new Object[] { new Object[] { "hello", null }, "hello" },
+                new Object[] { new Object[] { null, "hello" }, null },
+                new Object[] { new Object[] { "A", "B" }, "A" },
+        };
+
+        int iTestCase = 0;
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            ++iTestCase;
+            final Object[] input = (Object[]) TEST_CASE[0];
+            final Object expected = (Object) TEST_CASE[1];
+
+            assertEquals( iTestCase + " th test case", expected, ArrayUtil.pickupFirst( input ) );
+        }
+            }
+
+    /**
+     * Test {@link ArrayUtil#pickupLast(Collection)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ArrayUtil#pickupLast(Collection)
+     */
+    @Test
+    public void
+    test_pickupLast()
+            throws Exception
+            {
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null, null },
+                new Object[] { new Object[] { null }, null },
+                new Object[] { new Object[] { "hello", null }, null },
+                new Object[] { new Object[] { null, "hello" }, "hello" },
+                new Object[] { new Object[] { "A", "B" }, "B" },
+        };
+
+        int iTestCase = 0;
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            ++iTestCase;
+            final Object[] input = (Object[]) TEST_CASE[0];
+            final Object expected = (Object) TEST_CASE[1];
+
+            assertEquals( iTestCase + " th test case", expected, ArrayUtil.pickupLast( input ) );
+        }
+            }
+
+
+    /**
+     * Test {@link ArrayUtil#iterator(Object[])}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ArrayUtil#iterator(Object[])
+     */
+    @Test
+    public void test_iterator() throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null },
+                new Object[] { "hello" },
+                new Object[] { null, "hello" },
+                new Object[] { "A", "B" },
+        };
+
+        int iTestCase = 0;
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            ++iTestCase;
+            final Object[] array = TEST_CASE;
+            final ArrayList<Object> list = new ArrayList<Object>( Arrays.asList( array ) );
+            final Iterator<Object> iter = list.iterator();
+            final Iterator<Object> testTarget = ArrayUtil.iterator( array );
+
+            int iElement = 0;
+            while ( iter.hasNext() && testTarget.hasNext() )
+            {
+                assertEquals( iTestCase + " th test case :" + (++iElement) + " th element", iter.next(), testTarget.next() );
+            }
+            assertEquals( iTestCase + "th test case's last assert :", iter.hasNext(), testTarget.hasNext() );
+        }
+
+        try
+        {
+            final Object[] array = new Object[] { "a", "b", "c" };
+            final Iterator<Object> iter = ArrayUtil.iterator( array );
+            assertTrue( iter.hasNext() );
+            assertEquals( array[0], iter.next() );
+
+            array[1] = "d";
+
+            assertTrue( iter.hasNext() );
+            iter.next();
+            fail( "ConcurrentModificatoinException Test fail" );
+
+        } catch ( ConcurrentModificationException e )
+        {
+            // Test Success
+        }
+    }
+
+    /**
+     * Test {@link ArrayUtil#iterate(Object[], IteratingRunner, boolean)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see {@link ArrayUtil#iterate(Object[], IteratingRunner, boolean)}
+     */
+    @Test
+    public void test_iterator_with_iteratingRunner() {
+        final Object[][] TEST_CASES = new Object[][] {
+                null,
+                new Object[] { null },
+                new Object[] { "hello" },
+                new Object[] { null, "hello" },
+                new Object[] { "A", "B" },
+        };
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final Object[] array = TEST_CASE;
+
+            try {
+                ArrayUtil.iterate(array, null, false);
+            } catch (InvocationTargetException e1) {
+                fail("Failed iterate(Collection, null, false) test");
+            }
+
+            arrayIndex = 0;
+            successTest = true;
+            try {
+                ArrayUtil.iterate(array,
+                        new IteratingRunner<Object>() {
+                    @Override
+                    public void run(Object arg) {
+                        if ( successTest && arg != array[arrayIndex++] ) {
+                            successTest = false;
+                        }
+                    }
+                },
+                true);
+                if ( !successTest ) {
+                    fail("Failed iterate(Collection, IteratingRunner, true) test");
+                }
+            } catch (InvocationTargetException e) {
+                fail("Failed iterate(Collection, IteratingRunner, true) test");
+            }
+
+            arrayIndex = 0;
+            successTest = true;
+            try {
+                ArrayUtil.iterate(array,
+                        new IteratingRunner<Object>() {
+                    @Override
+                    public void run(Object arg) {
+                        if ( arg == null ) {
+                            successTest = false;
+                            return;
+                        }
+                        if ( successTest ) {
+                            for ( int i = arrayIndex ; i < array.length ; i++ ) {
+                                if( array[i] == null ) {
+                                    continue;
+                                }
+                                if ( arg != array[i] ) {
+                                    successTest = false;
+                                    return;
+                                }
+                                else {
+                                    arrayIndex = ++i;
+                                }
+                            }
+                        }
+                    }
+                },
+                false);
+                if ( !successTest ) {
+                    fail("Failed iterate(Collection, IteratingRunner, false) test");
+                }
+            } catch (InvocationTargetException e) {
+                fail("Failed iterate(Collection, IteratingRunner, false) test");
+            }
+        }
+    }
+
+
+    /**
+     * Test {@link ArrayUtil#convertToWrapper(char[])}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ArrayUtil#convertToWrapper(char[])
+     */
+    @Test
+    public void test_convertToWrapper() throws Exception
+    {
+        final char[] input = "hello".toCharArray();
+        final Character[] ret = ArrayUtil.convertToWrapper( input );
+
+        assertEquals( input.length, ret.length );
+    }
+
+    /**
+     * Test {@link ArrayUtil#filter(Object[], IteratingAcceptor, boolean)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ArrayUtil#filter(Object[], IteratingAcceptor, boolean)
+     */
+    @Test
+    public void test_filter() throws Exception
+    {
+        final Character[] input = ArrayUtil.convertToWrapper( "hello".toCharArray() );
+
+        assertTrue( Arrays.equals(
+                new Character[] { 'l', 'l' },
+                ArrayUtil.filter( input, new IteratingAcceptor<Character>() {
+                        public boolean accept( Character arg)
+                        {
+                            return ( 'l' == arg );
+                        }
+                }, true )
+        ) );
+    }
+
+    @Test
+    public void test_toObjectArray() {
+        final Object[][] inputArray = new Object[][]{
+                null,
+                new String[]{"hello", "test", "java"},
+                new Integer[]{10, 20, 30},
+                {10,20,30},
+                {true, false, true},
+                {true, 10, false},
+                new Object[]{"hello", 10, 5},
+                new Object[]{5, "java", 5},
+                new Object[]{null, "hello", 10},
+                new Object[]{null, null, null},
+                new Object[]{ }
+        };
+
+        final int inputInt[] = {10,20,30};
+        final boolean inputBool[] = {true, false, false};
+
+        Object[] actualData = null;
+
+        for ( Object[] input : inputArray ) {
+            actualData = ArrayUtil.toObjectArray(input);
+            if ( (input == null || input.length == 0) ) {
+                if ( actualData.length != 0 ) {
+                    fail("Failed toObjectArray(object) test");
+                }
+            }
+            else {
+                if ( input != actualData) {
+                    fail("Failed toObjectArray(object) test");
+                }
+            }
+        }
+
+        actualData = ArrayUtil.toObjectArray(inputInt);
+        if ( !(actualData instanceof Integer[]) ) {
+            fail("Failed toObjectArray(int[]) test");
+        }
+        actualData = ArrayUtil.toObjectArray(inputBool);
+        if ( !(actualData instanceof Boolean[]) ) {
+            fail("Failed toObjectArray(boolean[]) test");
+        }
+    }
+
+    @Test
+    public void test_size_primitive(){
+        final boolean[][] inputBool = {
+                null,
+                {false},
+                {true, true},
+        };
+        final byte[][] inputByte = {
+                null,
+                {0x00},
+                {0x1a, 0x10},
+        };
+        final char[][] inputChar = {
+                null,
+                {'a'},
+                {'a', 'b'}
+        };
+        final short[][] inputShort = {
+                null,
+                {1},
+                {10, 20}
+        };
+        final int[][] inputInt = {
+                null,
+                {100},
+                {200, 300}
+        };
+        final long[][] inputLong = {
+                null,
+                {100l},
+                {200l, 300l}
+        };
+        final float[][] inputFloat = {
+                null,
+                {100f},
+                {200f, 300f}
+        };
+        final double[][] inputDouble = {
+                null,
+                {100d},
+                {200d, 300d}
+        };
+        int size = 0;
+
+        for ( boolean[] input : inputBool ) {
+            size = ArrayUtil.size(input);
+            if ( input == null ) {
+                if ( size != 0 ) {
+                    fail("Failed size(boolean[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, ArrayUtil.size(input));
+            }
+        }
+
+        for ( byte[] input : inputByte ) {
+            size = ArrayUtil.size(input);
+            if ( input == null ) {
+                if ( size != 0 ) {
+                    fail("Failed size(byte[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, ArrayUtil.size(input));
+            }
+        }
+
+        for ( char[] input : inputChar ) {
+            size = ArrayUtil.size(input);
+            if ( input == null ) {
+                if ( size != 0 ) {
+                    fail("Failed size(char[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, ArrayUtil.size(input));
+            }
+        }
+
+        for ( short[] input : inputShort ) {
+            size = ArrayUtil.size(input);
+            if ( input == null ) {
+                if ( size != 0 ) {
+                    fail("Failed size(short[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, ArrayUtil.size(input));
+            }
+        }
+
+        for ( int[] input : inputInt ) {
+            size = ArrayUtil.size(input);
+            if ( input == null ) {
+                if ( size != 0 ) {
+                    fail("Failed size(int[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, ArrayUtil.size(input));
+            }
+        }
+
+        for ( long[] input : inputLong ) {
+            size = ArrayUtil.size(input);
+            if ( input == null ) {
+                if ( size != 0 ) {
+                    fail("Failed size(long[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, ArrayUtil.size(input));
+            }
+        }
+
+        for ( float[] input : inputFloat ) {
+            size = ArrayUtil.size(input);
+            if ( input == null ) {
+                if ( size != 0 ) {
+                    fail("Failed size(float[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, ArrayUtil.size(input));
+            }
+        }
+
+        for ( double[] input : inputDouble ) {
+            size = ArrayUtil.size(input);
+            if ( input == null ) {
+                if ( size != 0 ) {
+                    fail("Failed size(double[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, ArrayUtil.size(input));
+            }
+        }
+    }
+
+    @Test
+    public void test_size() {
+        final Object[][] inputArray = new Object[][]{
+                null,
+                new String[]{"hello", "test", "java"},
+                new Integer[]{10, 20, 30},
+                {10,20,30},
+                {true, false, true},
+                {true, 10, false},
+                new Object[]{"hello", 10, 5},
+                new Object[]{5, "java", 5},
+                new Object[]{null, "hello", 10},
+                new Object[]{null, null, null},
+                new Object[]{ }
+        };
+        final int inputInt[] = {10,20,30};
+        final boolean inputBool[] = {true, false, false};
+
+        int size = 0;
+        int size2 = 0;
+        for ( Object[] input : inputArray ) {
+            size = ArrayUtil.size(input);
+            if ( input == null || input.length == 0 ) {
+                if (size != 0) {
+                    fail("Failed size(T[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, size);
+            }
+
+            size2 = ArrayUtil.size((Object)input);
+            if ( input == null || input.length == 0 ) {
+                if (size2 != 0) {
+                    fail("Failed size(T[]) test");
+                }
+            }
+            else {
+                assertEquals(input.length, size2);
+            }
+        }
+
+        assertEquals("Failed size(Object) test", inputInt.length, ArrayUtil.size((Object)inputInt));
+        assertEquals("Failed size(Object) test", inputInt.length, ArrayUtil.size((Object)inputBool));
+    }
+
+    @Test
+    public void test_add() {
+        final Object[][] inputArray = new Object[][]{
+                null,
+                new String[]{"hello", "test", "java"},
+                new Integer[]{10, 20, 30},
+                {10,20,30},
+                {true, false, true},
+                {true, 10, false},
+                new Object[]{"hello", 10, 5},
+                new Object[]{5, "java", 5},
+                new Object[]{null, "hello", 10},
+                new Object[]{null, null, null},
+                new Object[]{ }
+        };
+        final Object[] inputAddArg = new Object[]{
+                null,
+                "hello",
+                10,
+                true
+        };
+
+        Object[] actualData = null;
+
+        for ( Object[] input : inputArray ) {
+            for ( Object arg : inputAddArg ) {
+                try {
+                    actualData = ArrayUtil.add(input, arg);
+                } catch (ArrayStoreException e) {
+                    if ( input == null ) {
+                        fail("Failed add(T[], Object) test");
+                    }
+                    if ( arg.getClass().getName().equals(input[0].getClass().getName()) ) {
+                        fail("Failed add(T[], Object) test");
+                    }
+                    continue;
+                }
+                if ( input == null || input.length == 0 ) {
+                    assertEquals(1, actualData.length);
+                    assertEquals(arg, actualData[0]);
+                }
+                else {
+                    assertEquals(input.length + 1 , actualData.length);
+                    assertEquals(arg, actualData[input.length]);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void test_remove() {
+
+        assertArrayEquals( new String[] { "a", "b", "c" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, -1 ) );
+        assertArrayEquals( new String[] { "b", "c" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, 0 ) );
+        assertArrayEquals( new String[] { "a", "c" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, 1 ) );
+        assertArrayEquals( new String[] { "a", "b" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, 2 ) );
+        assertArrayEquals( new String[] { "a", "b", "c" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, 3 ) );
+
+        assertArrayEquals( new String[] { "a", "b", "c" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, -1, 0 ) );
+        assertArrayEquals( new String[] { "b", "c" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, 0, 1 ) );
+        assertArrayEquals( new String[] { "a", "c" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, 1, 2 ) );
+        assertArrayEquals( new String[] { "a", "b" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, 2, 3 ) );
+        assertArrayEquals( new String[] { "a", "b", "c" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, 3, 4 ) );
+
+        assertArrayEquals( new String[] { "c" }, ArrayUtil.remove( new String[] { "a", "b", "c" }, -1, 2 ) );
+
+        final Object[][] inputArray = new Object[][]{
+                null,
+                new String[]{"hello", "test", "java", "c", "c++", "junit", "time"},
+                new Integer[]{10, 20, 30, 40, 50, 60, 70, 80, 90},
+                {10, 20, 30, 40, 50, 60, 70, 80, 90, 100},
+                {true, false, true, true, false, true, false},
+                {true, 10, false, 20, "test", "java", 30},
+                new Object[]{"hello", 10, 5, 20, 30, true},
+                new Object[]{5, "java", 5},
+                new Object[]{null, "hello", 10},
+                new Object[]{null, null, null},
+                new Object[]{ }
+        };
+        Object[] actualData = null;
+
+        for ( Object[] input : inputArray ) {
+            for ( int i = -1 ; i < 10 ; i++ ) {
+                for( int j = -1 ; j < 10 ; j++ ) {
+                    int deleteCount = 0;
+                    try {
+                        actualData = ArrayUtil.remove( input, i, j);
+                        i = Math.max( 0, i );
+                        if( j <= i) {
+                            assertArrayEquals(input , actualData);
+                        }
+                        else {
+                            deleteCount = j - i;
+                            for ( int k = 0 ; k < actualData.length ; k++ ) {
+                                if ( k >= i ) {
+                                    assertEquals(
+                                            "K:" + k + ", J:" + j + ", I:" +i + ", Input :" + input[k + deleteCount] + ", Actual :" + actualData[k],
+                                            input[k+deleteCount], actualData[k]);
+                                }
+                                else {
+                                    assertEquals(
+                                            "K:" + k + ", J:" + j + ", I:" +i + ", Input :" + input[k] + ", Actual :" + actualData[k],
+                                            input[k], actualData[k]);
+                                }
+
+                            }
+                        }
+                    }
+                    catch ( ArrayIndexOutOfBoundsException e ) {
+                        if ( j >= input.length || i >= input.length ) {
+                            continue;
+                        }
+                        else {
+                            fail("Failed remove(Object[], i : " + i + " , j : " + j + ") test");
+                        }
+                    }
+                    catch ( IllegalArgumentException e ) {
+                        if ( i >= j ) {
+                            continue;
+                        }
+                        else {
+                            fail("Failed remove(Object[], int, int) test");
+                        }
+                    }
+                    catch ( NullPointerException e ){
+                        if ( input == null) {
+                            continue;
+                        }
+                        else {
+                            fail("Failed remove(Object[], int, int) test");
+                        }
+                    }
+                    catch (NegativeArraySizeException e) {
+                        if ( input.length < j - i ) {
+                            continue;
+                        }
+                        else {
+                            fail("Failed remove(Object[], int, int) test");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    public void test_contains() {
+        final Object[][] inputArray = new Object[][]{
+                null,
+                new String[]{"hello", "test", "java"},
+                new Integer[]{10, 20, 30},
+                {10,20,30},
+                {true, false, true},
+                {true, 10, false},
+                new Object[]{"hello", 10, 5},
+                new Object[]{5, "java", 5},
+                new Object[]{null, "hello", 10},
+                new Object[]{null, null, null},
+                new Object[]{ }
+        };
+        final Object[] inputElement = new Object[]{
+                10583,
+                "zxcvb",
+        };
+
+        boolean actualData = true;
+
+        for ( Object[] input : inputArray ) {
+            if ( input == null ) {
+                actualData = ArrayUtil.contains(input, "blah");
+                assertEquals( false, actualData );
+            }
+            else {
+                for ( Object element : input) {
+                    actualData = ArrayUtil.contains(input, element);
+                    assertEquals( true, actualData );
+                }
+            }
+            for ( Object element : inputElement ) {
+                actualData = ArrayUtil.contains(input, element);
+                assertEquals( false, actualData );
+            }
+        }
+    }
+
+    @Test
+    public void test_get() {
+        final Object[][] inputArray = new Object[][]{
+                null,
+                new String[]{"hello", "test", "java"},
+                new Integer[]{10, 20, 30},
+                {10,20,30},
+                {true, false, true},
+                {true, 10, false},
+                new Object[]{"hello", 10, 5},
+                new Object[]{5, "java", 5},
+                new Object[]{null, "hello", 10},
+                new Object[]{null, null, null},
+                new Object[]{ }
+        };
+
+        for( Object[] input : inputArray) {
+            if ( input == null || input.length == 0 ) {
+                assertEquals( null, ArrayUtil.get(input, -1) );
+                assertEquals( null, ArrayUtil.get(input, 0) );
+            }
+            else {
+                assertEquals(null, ArrayUtil.get(input, -1) );
+                assertEquals( input[0], ArrayUtil.get(input, 0) );
+                assertEquals(null, ArrayUtil.get(input, input.length + 1) );
+            }
+        }
+    }
+    
+    public
+    void
+    test_safe()
+    throws Exception
+    {
+        final String[][] TEST_CASES = new String[][] {
+            null,
+            new String[] { null, "aaa" },
+            new String[] { "hello", "world" },
+        };
+        
+        for ( final String[] TEST_CASE : TEST_CASES )
+        {
+            assertNotNull( safe( TEST_CASE ) );
+            for ( final String value : safe( TEST_CASE ) )
+            {
+                assertTrue( "value :" + value, true );
+            }
+        }
+        
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/AssertTest.java b/org.tizen.common/test/src/org/tizen/common/util/AssertTest.java
new file mode 100644 (file)
index 0000000..22ed64d
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+/**
+ * AssertTest
+ *
+ * Test case for {@link Assert}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see Assert
+ */
+public class
+AssertTest
+{
+       /**
+        * Test {@link Assert#fail(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Assert#fail(String)}
+        */
+       @Test
+       public
+       void
+       test_fail()
+       throws Exception
+       {
+               try
+               {
+                       Assert.fail( "Hello" );
+                       fail();
+               }
+               catch ( final IllegalArgumentException e )
+               {
+                       assertEquals( "Hello", e.getMessage() );
+               }
+       }
+
+       /**
+        * Test {@link Assert#isTrue(boolean)} and
+        * {@link Assert#isTrue(boolean, String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Assert#isTrue(boolean)}
+        * @see {@link Assert#isTrue(boolean, String)}
+        */
+       @Test
+       public
+       void 
+       test_assertTrue()
+       throws Exception
+       {
+               int a = 5;
+               int b = 2;
+               Assert.isTrue( 3 == a-b, "Good case" );
+               
+               Assert.isTrue( 3 == a-b );
+               Assert.isTrue( "abc".equals( "abc" ) );
+               try
+               {
+                       Assert.isTrue( 3==4 );
+                       fail();
+               }
+               catch ( final IllegalArgumentException e )
+               {
+               }
+               
+       }
+
+       /**
+        * Test {@link Assert#assertFalse(boolean)} and
+        * {@link Assert#assertFalse(boolean, String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Assert#assertFalse(boolean)}
+        * @see {@link Assert#assertFalse(boolean, String)}
+        */
+       @Test
+       public void
+       test_assertFalse()
+       throws Exception
+       {
+               Assert.isFalse( 3 == 4, "Assertion passed" );
+               Assert.isFalse( 3 == 4 );
+       }
+       
+       /**
+        * Test {@link Assert#isNull(Object)} and
+        * {@link Assert#isNull(Object, String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Assert#isNull(Object)}
+        * @see {@link Assert#isNull(Object, String)}
+        */
+       @Test
+       public
+       void
+       test_assertNull()
+       throws Exception
+       {
+               Assert.isNull( null );
+               Assert.isNull( null, "Assertion passed" );
+       }
+       
+       /**
+        * Test {@link Assert#notNull(boolean)} and
+        * {@link Assert#notNull(boolean, String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Assert#notNull(boolean)}
+        * @see {@link Assert#notNull(boolean, String)}
+        */
+       @Test
+       public
+       void
+       test_notNull()
+       throws Exception
+       {
+               
+               Assert.notNull( new Object() );
+               Assert.notNull( "Hello", "Assertion passed" );
+               
+       }
+       
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/CollectionMapTest.java b/org.tizen.common/test/src/org/tizen/common/util/CollectionMapTest.java
new file mode 100644 (file)
index 0000000..95c6140
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+
+/**
+ * CollectionMapTest
+ *
+ * Test case for {@link CollectionMap}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see CollectionMap
+ */
+public class
+CollectionMapTest
+{
+       /**
+        * Test {@link CollectionMap#put(Object, Object)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see CollectionMap#put(Object, Object)
+        */
+       public
+       void
+       test_put()
+       throws Exception {
+               final CollectionMap<String, String> map = new CollectionMap<String, String>();
+               
+               map.put( "hello", "world1" );
+               
+               assertEquals( Arrays.asList( "world1" ), map.get( "hello" ) );
+               map.put( "hello", "world2" );
+               assertEquals( Arrays.asList( "world1", "world2" ), map.get( "hello" ) );
+       }
+       
+       
+       /**
+        * Test {@link CollectionMap#get(Object)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see CollectionMap#get(Object)
+        */
+       @Test
+       public
+       void
+       test_get()
+       throws Exception
+       {
+               final CollectionMap<String, String> map = new CollectionMap<String, String>();
+               
+               map.put( "hello", "world1" );
+               
+               assertEquals( Arrays.asList( "world1" ), map.get( "hello" ) );
+               map.put( "hello", "world2" );
+               assertEquals( Arrays.asList( "world1", "world2" ), map.get( "hello" ) );
+       }
+       
+       /**
+        * Test {@link CollectionMap#remove(Object)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see CollectionMap#remove(Object)
+        */
+       @Test
+       public
+       void
+       test_remove()
+       throws Exception
+       {
+               final CollectionMap<String, String> map = new CollectionMap<String, String>();
+               
+               map.put( "hello", "world1" );
+               map.put( "hello", "world2" );
+               assertEquals( Arrays.asList( "world1", "world2" ), map.get( "hello" ) );
+
+               map.remove( "hello", "world1" );
+               assertEquals( Arrays.asList( "world2" ), map.get( "hello" ) );
+               map.remove( "hello", "world1" );
+               assertEquals( Arrays.asList( "world2" ), map.get( "hello" ) );
+               map.remove( "hello", "world2" );
+               assertEquals( null, map.get( "hello" ) );
+       }
+       
+
+       /**
+        * Test {@link CollectionMap#toString()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see CollectionMap#toString()
+        */
+       @Test
+       public
+       void
+       test_toString()
+       throws Exception
+       {
+               final CollectionMap<String, String> map = new CollectionMap<String, String>();
+               map.put( "a", "b" );
+               map.put( "a", "c" );
+               
+               assertEquals( "CollectionMap[a=[b, c]]", map.toString() );
+               
+               map.put( "c", "d" );
+               assertEquals( "CollectionMap[a=[b, c], c=[d]]", map.toString() );
+       }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/CollectionUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/CollectionUtilTest.java
new file mode 100644 (file)
index 0000000..cbce552
--- /dev/null
@@ -0,0 +1,950 @@
+/*
+ * Common
+ *
+ * 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.common.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+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 java.util.Vector;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.Test;
+
+
+/**
+ * CollectionUtilsTest
+ *
+ * Test case for {@link CollectionUtil}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * @author GyeongSeok Seo{@literal <gyeongseok.seo@samsung.com>} (S-Core)
+ * 
+ * @see CollectionUtil
+ */
+public class
+CollectionUtilTest
+{
+    /**
+     * Test {@link CollectionUtil#isEmpty(java.util.Collection)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see CollectionUtil#isEmpty(java.util.Collection)
+     */
+    @Test
+    @SuppressWarnings("serial")
+    public void test_isEmpty() throws Exception
+    {
+        assertTrue( CollectionUtil.isEmpty( null ) );
+        assertTrue( CollectionUtil.isEmpty( new HashSet<Object>() ) );
+        assertTrue( CollectionUtil.isEmpty( new HashMap<String, Object>().keySet() ) );
+        assertFalse( CollectionUtil.isEmpty( new ArrayList<Object>() {{ add("Hello"); }} ) );
+        assertFalse( CollectionUtil.isEmpty( new ArrayList<Object>( Arrays.asList( "Hello" ) ) ) );
+    }
+
+    /**
+     *  Test {@link CollectionUtil#size(java.util.Collection)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see CollectionUtil#size(java.util.Collection)
+     */
+    @SuppressWarnings("unchecked")
+       @Test
+    public void test_size() throws Exception
+    {
+        assertEquals( 0, CollectionUtil.size( null ) );
+
+        /* Mock Object using Mockito */
+        final ArrayList<Object> list = mock( ArrayList.class );
+
+        when( list.size() ).thenReturn( 3 );
+        assertEquals( 3, CollectionUtil.size(list) );
+        verify( list ).size();
+
+        final HashMap<String, Object> map = new HashMap<String, Object>();
+        assertEquals( 0, CollectionUtil.size( map.keySet() ) );
+
+        map.put("Hello", 1);
+        map.put("Tizen", 2);
+        assertEquals( 2, CollectionUtil.size( map.keySet() ) );
+    }
+
+    /**
+     * Test {@link CollectionUtil#iterate(java.util.Collection, IteratingRunner)}
+     * and {@link CollectionUtil#iterate(java.util.Collection, IteratingRunner, boolean)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see {@link CollectionUtil#iterate(java.util.Collection, IteratingRunner)}
+     * @see {@link CollectionUtil#iterate(java.util.Collection, IteratingRunner, boolean)}
+     */
+    @Test
+    public void test_iterate() throws Exception
+    {
+        final AtomicInteger count = new AtomicInteger();
+
+        CollectionUtil.iterate(
+                new ArrayList<String>( Arrays.asList(
+                        "hello", "Hello", "World", null, "Test"
+                ) ),
+                new IteratingRunner<String>()
+                {
+                    public void run(String arg)
+                    {
+                        if ( Character.isUpperCase( arg.charAt( 0 ) ) )
+                        {
+                            count.incrementAndGet();
+                        }
+                    }
+                }
+        );
+
+        assertEquals( 3, count.get() );
+
+        count.set( 0 );
+        CollectionUtil.iterate(
+                new ArrayList<String>( Arrays.asList(
+                        "hello", "Hello", "World", null, "Test"
+                ) ),
+                new IteratingRunner<String>()
+                {
+                    public void run( final String arg)
+                    {
+                        throw new IllegalStateException();
+                    }
+                },
+                true
+        );
+        assertEquals( 0, count.get() );
+    }
+
+    /**
+     * Test {@link CollectionUtil#filter(java.util.Collection, java.util.Collection, IteratingAcceptor, boolean)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see {@link CollectionUtil#filter(java.util.Collection, java.util.Collection, IteratingAcceptor, boolean)}
+     */
+    @Test
+    public void test_filter() throws Exception
+    {
+        final ArrayList<String> results = new ArrayList<String>();
+
+        CollectionUtil.filter(
+                null,
+                results,
+                new IteratingAcceptor<String>()
+                {
+                    @Override
+                    public boolean accept(String arg) {
+                        return true;
+                    }
+                },
+                true
+        );
+        assertEquals( 0, CollectionUtil.size(results) );
+
+        results.clear();
+        CollectionUtil.filter(
+                new ArrayList<String>( Arrays.asList(
+                        "hello", "Hello", "World", null, "Test"
+                ) ),
+                results,
+                new IteratingAcceptor<String>()
+                {
+                    @Override
+                    public boolean accept(String arg) {
+                        if ( arg != null && Character.isUpperCase( arg.charAt( 0 ) ) )
+                        {
+                            return true;
+                        }
+                        return false;
+                    }
+                },
+                true
+        );
+        assertEquals( 3, CollectionUtil.size(results) );
+
+        results.clear();
+        CollectionUtil.filter(
+                new ArrayList<String>( Arrays.asList(
+                        "hello", "Hello", "World", null, "Test"
+                ) ),
+                results,
+                new IteratingAcceptor<String>()
+                {
+                    @Override
+                    public boolean accept(String arg) {
+                        if ( arg != null && Character.isUpperCase( arg.charAt( 0 ) ) )
+                        {
+                            return true;
+                        }
+                        throw new IllegalStateException();
+                    }
+                },
+                true
+        );
+        assertEquals( 3, CollectionUtil.size(results) );
+    }
+
+    /**
+     * Test {@link CollectionUtil#pickupFirst(Collection)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see {@link CollectionUtil#pickupFirst(Collection)}
+     */
+    @Test
+    public void
+    test_pickupFirst()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null, null },
+                new Object[] { new Object[] { null }, null },
+                new Object[] { new Object[] { "hello", null }, "hello" },
+                new Object[] { new Object[] { null, "hello" }, null },
+                new Object[] { new Object[] { "A", "B" }, "A" },
+        };
+
+        int iTestCase = 0;
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+                       ++iTestCase;
+            final Object[] closeables = (Object[]) TEST_CASE[0];
+            final Object expected = (Object) TEST_CASE[1];
+
+            Collection<Object> collection = null;
+            if ( null != closeables )
+            {
+                collection = Arrays.asList( closeables );
+            }
+
+            assertEquals( iTestCase + " th test case", expected, CollectionUtil.pickupFirst( collection ) );
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#pickupLast(Collection)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see {@link CollectionUtil#pickupLast(Collection)}
+     */
+    @Test
+    public void
+    test_pickupLast()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null, null },
+                new Object[] { new Object[] { null }, null },
+                new Object[] { new Object[] { "hello", null }, null },
+                new Object[] { new Object[] { null, "hello" }, "hello" },
+                new Object[] { new Object[] { "A", "B" }, "B" },
+        };
+
+        int iTestCase = 0;
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+                       ++iTestCase;
+            final Object[] closeables = (Object[]) TEST_CASE[0];
+            final Object expected = (Object) TEST_CASE[1];
+
+            Collection<Object> collection = null;
+            if ( null != closeables )
+            {
+                collection = Arrays.asList( closeables );
+            }
+
+            assertEquals( iTestCase + " th test case", expected, CollectionUtil.pickupLast( collection ) );
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#iterator(Enumeration)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see {@link CollectionUtil#iterator(Enumeration)}
+     */
+    @Test
+    public
+    void
+    test_iterator()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null },
+                new Object[] { "hello" },
+                new Object[] { null, "hello" },
+                new Object[] { "A", "B" },
+        };
+
+        int iTestCase = 0;
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+                       ++iTestCase;
+            final Object[] array = TEST_CASE;
+            final Vector<Object> list = new Vector<Object>( Arrays.asList( array ) );
+            final Iterator<Object> iter = list.iterator();
+            final Enumeration<Object> enumeration = list.elements();
+
+            final Iterator<Object> testTarget = CollectionUtil.iterator( enumeration );
+            int iElement = 0;
+            while ( iter.hasNext() && testTarget.hasNext() )
+            {
+                assertEquals( iTestCase + " th test case :" + (++iElement) + " th element", iter.next(), testTarget.next() );
+            }
+            assertEquals( iter.hasNext(), testTarget.hasNext() );
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#asList(Object)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see {@link CollectionUtil#asList(Object)}
+     */
+    @Test
+    public
+    void
+    test_asList()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null, null },
+                new Object[] { new Object[] { null }, null },
+                new Object[] { new Object[] { "hello", null }, null },
+                new Object[] { new Object[] { null, "hello" }, "hello" },
+                new Object[] { new Object[] { "A", "B" }, "B" },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            assertTrue( CollectionUtil.asList(TEST_CASE) instanceof List );
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#mergeArrayIntoCollection(Object, Collection)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#mergeArrayIntoCollection(Object, Collection)}
+     */
+    @Test
+    public
+    void
+    test_mergeArrayIntoCollection()
+    throws Exception
+    {
+        final ArrayList<Object> list = new ArrayList<Object>();
+        list.add( "Tizen" );
+        list.add( "Test" );
+
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null, null },
+                new Object[] { new Object[] { null }, null },
+                new Object[] { new Object[] { "hello", null }, null },
+                new Object[] { new Object[] { null, "hello" }, "hello" },
+                new Object[] { new Object[] { "A", "B" }, "B" },
+        };
+
+        try {
+            CollectionUtil.mergeArrayIntoCollection( TEST_CASES[0], null );
+            fail( "mergeArrayIntoCollection must throw exception" );
+        } catch (NullPointerException e) {
+        }
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final int count = TEST_CASE.length + CollectionUtil.size( list );
+            CollectionUtil.mergeArrayIntoCollection( TEST_CASE, list );
+            assertEquals( count, CollectionUtil.size( list ) );
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#contains(Collection, Object)}
+     * and {@link CollectionUtil#contains(Enumeration, Object)}
+     * and {@link CollectionUtil#contains(Iterator, Object)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#contains(Collection, Object)}
+     * @see {@link CollectionUtil#contains(Enumeration, Object)}
+     * @see {@link CollectionUtil#contains(Iterator, Object)}
+     */
+    @Test
+    public
+    void
+    test_contains()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null },
+                new Object[] { "hello" },
+                new Object[] { null, "hello" },
+                new Object[] { "Tizen", "Test" },
+        };
+
+        assertFalse( CollectionUtil.contains( (Collection<Object>)null , null) );
+        assertFalse( CollectionUtil.contains( (Enumeration<Object>)null , null) );
+        assertFalse( CollectionUtil.contains( (Iterator<Object>)null , null) );
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final Object[] array = TEST_CASE;
+            final Vector<Object> list = new Vector<Object>( CollectionUtil.asList( array ) );
+            final Enumeration<Object> enumeration = list.elements();
+            final Iterator<Object> iter = CollectionUtil.iterator( list.elements() );
+            final Object element = list.get(0);
+            final Object element2 = "False";
+
+            assertTrue( CollectionUtil.contains( list, element ) );
+            assertTrue( CollectionUtil.contains( enumeration, element ) );
+            assertTrue( CollectionUtil.contains( iter, element ) );
+
+            assertFalse( CollectionUtil.contains( list, element2 ) );
+            assertFalse( CollectionUtil.contains( enumeration, element2 ) );
+            assertFalse( CollectionUtil.contains( iter, element2 ) );
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#containsAny(Collection, Collection)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#containsAny(Collection, Collection)}
+     */
+    @Test
+    public
+    void
+    test_containsAny()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] { null },
+                new Object[] { "hello" },
+                new Object[] { null, "hello" },
+                new Object[] { "Tizen", "Test" },
+        };
+
+        final ArrayList<String> candidates = new ArrayList<String>();
+        candidates.add(null);
+        candidates.add("hello");
+        candidates.add("Test");
+
+        final ArrayList<String> candidates2 = new ArrayList<String>();
+        candidates2.add("False");
+
+        final ArrayList<String> source = new ArrayList<String>();
+        source.add("Tizen");
+        source.add("Test");
+        source.add(null);
+
+        assertFalse( CollectionUtil.containsAny( (Collection<Object>)null , candidates) );
+        assertFalse( CollectionUtil.containsAny( source, (Collection<Object>)null ) );
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final Object[] array = TEST_CASE;
+            final Vector<Object> source2 = new Vector<Object>( CollectionUtil.asList( array ) );
+
+            assertTrue( CollectionUtil.containsAny( source2, candidates ) );
+            assertFalse( CollectionUtil.containsAny( source2, candidates2 ) );
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#isApproximableCollectionType(Class)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#isApproximableCollectionType(Class)}
+     */
+    @Test
+    public
+    void
+    test_isApproximableCollectionType()
+    throws Exception
+    {
+        final List<Class<?>> collectionTypeList = Arrays.asList( new Class<?>[] {
+                Collection.class,
+                Set.class, HashSet.class, SortedSet.class, LinkedHashSet.class, TreeSet.class,
+                List.class, LinkedList.class, ArrayList.class
+            } );
+
+        final List<Class<?>> mapTypeList = Arrays.asList( new Class<?>[] {
+                Map.class, SortedMap.class, HashMap.class, LinkedHashMap.class, TreeMap.class
+            } );
+
+        final List<Class<?>> generalTypeList = Arrays.asList( new Class<?>[] {
+                String.class, Integer.class, Exception.class, File.class
+            } );
+
+        assertFalse( CollectionUtil.isApproximableCollectionType( (Class<?>)null ) );
+
+        final Iterator<Class<?>> iter = collectionTypeList.iterator();
+        while( iter.hasNext() ) {
+            assertTrue( CollectionUtil.isApproximableCollectionType( iter.next() ) );
+        }
+
+        final Iterator<Class<?>> iter2 = mapTypeList.iterator();
+        while( iter2.hasNext() ) {
+            assertFalse( CollectionUtil.isApproximableCollectionType( iter2.next() ) );
+        }
+
+        final Iterator<Class<?>> iter3 = generalTypeList.iterator();
+        while( iter3.hasNext() ) {
+            assertFalse( CollectionUtil.isApproximableCollectionType( iter3.next() ) );
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#isApproximableMapType(Class)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#isApproximableMapType(Class)}
+     */
+    @Test
+    public
+    void
+    test_isApproximableMapType()
+    throws Exception
+    {
+        final List<Class<?>> collectionTypeList = Arrays.asList( new Class<?>[] {
+                Collection.class,
+                Set.class, HashSet.class, SortedSet.class, LinkedHashSet.class, TreeSet.class,
+                List.class, LinkedList.class, ArrayList.class
+            } );
+
+        final List<Class<?>> mapTypeList = Arrays.asList( new Class<?>[] {
+                Map.class, SortedMap.class, HashMap.class, LinkedHashMap.class, TreeMap.class
+            } );
+
+        final List<Class<?>> generalTypeList = Arrays.asList( new Class<?>[] {
+                String.class, Integer.class, Exception.class, File.class
+            } );
+
+        assertFalse( CollectionUtil.isApproximableMapType( (Class<?>)null ) );
+
+        final Iterator<Class<?>> iter = collectionTypeList.iterator();
+        while( iter.hasNext() ) {
+            assertFalse( CollectionUtil.isApproximableMapType( iter.next() ) );
+        }
+
+        final Iterator<Class<?>> iter2 = mapTypeList.iterator();
+        while( iter2.hasNext() ) {
+            assertTrue( CollectionUtil.isApproximableMapType( iter2.next() ) );
+        }
+
+        final Iterator<Class<?>> iter3 = generalTypeList.iterator();
+        while( iter3.hasNext() ) {
+            assertFalse( CollectionUtil.isApproximableMapType( iter3.next() ) );
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#createApproximableCollection(Collection, int)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#createApproximableCollection(Collection, int)}
+     */
+    @Test
+    public
+    void
+    test_createApproximableCollection()
+    throws Exception
+    {
+        final ArrayList<String> list = new ArrayList<String>( Arrays.asList(
+                "hello", "Hello", "World", null, "Test"
+                ) );
+
+        final HashMap<String, Object> map = new HashMap<String, Object>();
+        map.put("Hello", 1);
+        map.put("Tizen", 2);
+
+        Collection<?> result = CollectionUtil.createApproximableCollection( null, 5 );
+        assertTrue( CollectionUtil.isApproximableCollectionType( result.getClass() ) );
+        result.clear();
+
+        result = CollectionUtil.createApproximableCollection( list, 3 );
+        assertTrue( CollectionUtil.isApproximableCollectionType( result.getClass() ) );
+        result.clear();
+
+        result = CollectionUtil.createApproximableCollection( map.keySet(), 2 );
+        assertTrue( CollectionUtil.isApproximableCollectionType( result.getClass() ) );
+    }
+
+    /**
+     * Test {@link CollectionUtil#createApproximableMap(Map, int)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#createApproximableMap(Map, int)}
+     */
+    @Test
+    public
+    void
+    test_createApproximableMap()
+    throws Exception
+    {
+        final HashMap<String, Object> map = new HashMap<String, Object>();
+        map.put("Hello", 1);
+        map.put("Tizen", 2);
+
+        Map<?,?> result = CollectionUtil.createApproximableMap( null, 5 );
+        assertTrue( CollectionUtil.isApproximableMapType( result.getClass() ) );
+        result.clear();
+
+        result = CollectionUtil.createApproximableMap( map, 1 );
+        assertTrue( CollectionUtil.isApproximableMapType( result.getClass() ) );
+    }
+
+    /**
+     * Test {@link CollectionUtil#toString(Object)}
+     * and {@link CollectionUtil#toString(boolean[])}
+     * and {@link CollectionUtil#toString(char[])}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#toString(Object)}
+     * @see {@link CollectionUtil#toString(boolean[])}
+     * @see {@link CollectionUtil#toString(char[])}
+     */
+    @Test
+    public
+    void
+    test_toString()
+    throws Exception
+    {
+        Object obj = (Object)new ArrayList<String>( Arrays.asList(
+                "hello", "Hello", "World", null, "Test"
+                ) );
+        boolean [] booleanArray = { true, false };
+        boolean [] booleanArray2 = {};
+        char [] charArray = { 'T', 'i', 'Z', 'e', 'N' };
+        char [] charArray2 = {};
+
+        // toString(Object)
+        String result = CollectionUtil.toString( (Object)null );
+        assertEquals( StringUtil.NULL_STRING, result);
+        result = CollectionUtil.toString( (Object)booleanArray );
+        assertEquals( "{true, false}", result );
+        result = CollectionUtil.toString( (Object)charArray );
+        assertEquals( "{T, i, Z, e, N}", result );
+        result = CollectionUtil.toString(obj);
+        assertEquals( "[hello, Hello, World, null, Test]", result);
+
+        // toString(boolean[])
+        result = CollectionUtil.toString( (boolean[])null );
+        assertEquals( StringUtil.NULL_STRING, result);
+        result = CollectionUtil.toString( booleanArray );
+        assertEquals( "{true, false}", result );
+        result = CollectionUtil.toString( booleanArray2 );
+        assertEquals( "{}", result );
+
+        // toString(char[])
+        result = CollectionUtil.toString( (char[])null );
+        assertEquals( StringUtil.NULL_STRING, result);
+        result = CollectionUtil.toString( charArray );
+        assertEquals( "{T, i, Z, e, N}", result );
+        result = CollectionUtil.toString( charArray2 );
+        assertEquals( "{}", result );
+    }
+
+    /**
+     * Test {@link CollectionUtil#concatenate(Collection, String)}
+     * and {@link CollectionUtil#concatenate(Object[], String)}
+     * and {@link CollectionUtil#concatenate(Iterator, String)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#concatenate(Collection, String)}
+     * @see {@link CollectionUtil#concatenate(Object[], String)}
+     * @see {@link CollectionUtil#concatenate(Iterator, String)}
+     */
+    @Test
+    public
+    void
+    test_concatenate()
+    throws Exception
+    {
+        final String separator = "$";
+
+        final Object[][] TEST_CASES = new Object[][] {
+                new Object[] {},
+                new Object[] { null },
+                new Object[] { "hello" },
+                new Object[] { null, "hello" },
+                new Object[] { "Tizen", "Test" },
+        };
+
+        assertEquals( StringUtil.NULL_STRING,
+                CollectionUtil.concatenate( (Object[])null, separator ) );
+        assertEquals( StringUtil.NULL_STRING,
+                CollectionUtil.concatenate( (Collection<Object>)null, separator) );
+        assertEquals( StringUtil.NULL_STRING,
+                CollectionUtil.concatenate( (Iterator<Object>)null, separator) );
+
+        int count = 0;
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            count++;
+            final Object[] array = TEST_CASE;
+            final Vector<Object> list = new Vector<Object>( CollectionUtil.asList( array ) );
+            Iterator<Object> iter = CollectionUtil.iterator( list.elements() );
+
+            switch (count) {
+                case 1:
+                    assertEquals( "{}",
+                            CollectionUtil.concatenate( array, separator ) );
+                    assertEquals( "{}",
+                            CollectionUtil.concatenate( list, separator ) );
+                    assertEquals( "{}",
+                            CollectionUtil.concatenate( iter, separator ) );
+                    break;
+                case 2:
+                    assertEquals( StringUtil.NULL_STRING,
+                            CollectionUtil.concatenate( array, separator ) );
+                    assertEquals( StringUtil.NULL_STRING,
+                            CollectionUtil.concatenate( list, separator ) );
+                    assertEquals( StringUtil.NULL_STRING,
+                            CollectionUtil.concatenate( iter, separator ) );
+                    break;
+                case 3:
+                    assertEquals( "hello",
+                            CollectionUtil.concatenate( array, separator ) );
+                    assertEquals( "hello",
+                            CollectionUtil.concatenate( list, separator ) );
+                    assertEquals( "hello",
+                            CollectionUtil.concatenate( iter, separator ) );
+                    break;
+                case 4:
+                    assertEquals( StringUtil.NULL_STRING+separator+"hello",
+                            CollectionUtil.concatenate( array, separator ) );
+                    assertEquals( StringUtil.NULL_STRING+separator+"hello",
+                            CollectionUtil.concatenate( list, separator ) );
+                    assertEquals( StringUtil.NULL_STRING+separator+"hello",
+                            CollectionUtil.concatenate( iter, separator ) );
+                    break;
+                case 5:
+                    assertEquals( "Tizen"+separator+"Test",
+                            CollectionUtil.concatenate( array, separator ) );
+                    assertEquals( "Tizen"+separator+"Test",
+                            CollectionUtil.concatenate( list, separator ) );
+                    assertEquals( "Tizen"+separator+"Test",
+                            CollectionUtil.concatenate( iter, separator ) );
+
+                    iter = CollectionUtil.iterator( list.elements() );
+                    assertEquals( "Tizen"+null+"Test",
+                            CollectionUtil.concatenate( array, null ) );
+                    assertEquals( "Tizen"+null+"Test",
+                            CollectionUtil.concatenate( list, null ) );
+                    assertEquals( "Tizen"+null+"Test",
+                            CollectionUtil.concatenate( iter, null ) );
+
+                    iter = CollectionUtil.iterator( list.elements() );
+                    assertEquals( "Tizen"+StringUtil.EMPTY_STRING+"Test",
+                            CollectionUtil.concatenate( array, StringUtil.EMPTY_STRING ) );
+                    assertEquals( "Tizen"+StringUtil.EMPTY_STRING+"Test",
+                            CollectionUtil.concatenate( list, StringUtil.EMPTY_STRING ) );
+                    assertEquals( "Tizen"+StringUtil.EMPTY_STRING+"Test",
+                            CollectionUtil.concatenate( iter, StringUtil.EMPTY_STRING ) );
+                    break;
+            }
+
+        }
+    }
+
+    /**
+     * Test {@link CollectionUtil#hashCode(Object)}
+     * and {@link CollectionUtil#hashCode(boolean[])}
+     * and {@link CollectionUtil#hashCode(int[])}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#hashCode(Object)}
+     * @see {@link CollectionUtil#hashCode(boolean[])}
+     * @see {@link CollectionUtil#hashCode(int[])}
+     */
+    @Test
+    public
+    void
+    test_hashCode()
+    throws Exception
+    {
+        Object obj = (Object)new ArrayList<String>( Arrays.asList(
+                "hello", "Hello", "World", null, "Test"
+                ) );
+        boolean [] booleanArray = { true, false };
+        boolean [] booleanArray2 = {};
+        int [] intArray = { 1, 2, 3, 4, 5 };
+        int [] intArray2 = {};
+
+        // hashCode(Object)
+        assertEquals( 0, CollectionUtil.hashCode( (Object)null ) );
+        assertTrue( 0 != CollectionUtil.hashCode(obj) );
+        assertTrue( 0 != CollectionUtil.hashCode( (Object)booleanArray ) );
+        assertTrue( 0 != CollectionUtil.hashCode( (Object)booleanArray2) );
+        assertTrue( 0 != CollectionUtil.hashCode( (Object)intArray) );
+        assertTrue( 0 != CollectionUtil.hashCode( (Object)intArray2) );
+        assertEquals( CollectionUtil.hashCode(obj), CollectionUtil.hashCode(obj) );
+
+        // hashCode(boolean[])
+        assertEquals( 0, CollectionUtil.hashCode( (boolean[])null ) );
+        assertTrue( 0 != CollectionUtil.hashCode( booleanArray ) );
+        assertTrue( 0 != CollectionUtil.hashCode( booleanArray2) );
+        assertTrue( CollectionUtil.hashCode(booleanArray) != CollectionUtil.hashCode(booleanArray2) );
+        assertEquals( CollectionUtil.hashCode(booleanArray), CollectionUtil.hashCode(booleanArray) );
+
+        // hashCode(int[])
+        assertEquals( 0, CollectionUtil.hashCode( (int[])null ) );
+        assertTrue( 0 != CollectionUtil.hashCode( intArray ) );
+        assertTrue( 0 != CollectionUtil.hashCode( intArray2) );
+        assertTrue( CollectionUtil.hashCode(intArray) != CollectionUtil.hashCode(intArray2) );
+        assertEquals( CollectionUtil.hashCode(intArray),  CollectionUtil.hashCode(intArray));
+    }
+
+    /**
+     * Test {@link CollectionUtil#equals(Collection...)}
+     * and {@link CollectionUtil#equals(Object[]...)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#equals(Collection...)}
+     * @see {@link CollectionUtil#equals(Object[]...)}
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public
+    void
+    test_equals()
+    throws Exception
+    {
+        final Object obj = (Object)new ArrayList<String>( Arrays.asList(
+                "hello", "Hello", "World", null, "Test"
+                ) );
+        final Object obj2 = (Object)Arrays.asList(
+                "hello", "Hello", "World", null, "Test"
+                );
+        final Boolean [] booleanArray = { true, false };
+        final Integer [] intArray = { 1, 2, 3, 4, 5 };
+        final Integer [] intArray2 = {};
+        final Object [] objectArray = { 1, 2, 3, 4, 5 };
+        final Object [] objectArray2 = { 1, 2, 3, 4, 5 };
+        final Vector<Object> list = new Vector<Object>( CollectionUtil.asList(objectArray) );
+
+        assertTrue( CollectionUtil.equals( (Object[])null, null) );
+        assertTrue( CollectionUtil.equals( (Collection<Object>)null, null) );
+
+        // equals(Object[]...)
+        assertTrue( CollectionUtil.equals( objectArray, objectArray2 ) );
+        assertTrue( CollectionUtil.equals( objectArray, (Object[])intArray ) );
+        assertFalse( CollectionUtil.equals( objectArray, (Object[])intArray2 ) );
+        assertFalse( CollectionUtil.equals( objectArray, (Object[])booleanArray ) );
+
+        // equals(COllection...)
+        assertTrue( CollectionUtil.equals( (Collection<?>)obj, (Collection<?>)obj2 ) );
+        assertFalse( CollectionUtil.equals( (Collection<?>)obj, (Collection<?>)list ) );
+    }
+
+    /**
+     * Test {@link CollectionUtil#swap(Object[], int, int)}
+     * 
+     * @throws Exception is case of failure in test
+     * 
+     * @see {@link CollectionUtil#swap(Object[], int, int)}
+     */
+    @Test
+    public
+    void
+    test_swap()
+    throws Exception
+    {
+        final Object [] objectArray = { 1, 2, 3, 4, 5 };
+
+        CollectionUtil.swap( objectArray, 0, 1 );
+        assertEquals( 2, objectArray[0] );
+        assertEquals( 1, objectArray[1] );
+
+        CollectionUtil.swap( objectArray, 1, 0 );
+        assertEquals( 1, objectArray[0] );
+        assertEquals( 2, objectArray[1] );
+
+        CollectionUtil.swap( objectArray, 0, 0 );
+        assertEquals( 1, objectArray[0] );
+        assertEquals( 2, objectArray[1] );
+
+        try {
+            CollectionUtil.swap( objectArray, 0, 5 );
+            fail( "swap must throw exception" );
+        } catch (Exception e) {
+        }
+
+        try {
+            CollectionUtil.swap( objectArray, -1, 0 );
+            fail( "swap must throw exception" );
+        } catch (Exception e) {
+        }
+
+        try {
+            CollectionUtil.swap( null, 0, 1 );
+            fail( "swap must throw exception" );
+        } catch (Exception e) {
+        }
+    }
+}
+
diff --git a/org.tizen.common/test/src/org/tizen/common/util/EFSUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/EFSUtilTest.java
new file mode 100644 (file)
index 0000000..27097d2
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact: 
+* Jihoon Song <jihoon80.song@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.common.util;
+
+import java.net.URI;
+import java.net.URL;
+
+import org.junit.*;
+import org.tizen.common.Surrogate;
+import org.tizen.common.util.EFSUtil.DialogChoicer;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileInfo;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.filesystem.IFileSystem;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.swt.widgets.Shell;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+/**
+ * EFSUtilTest.
+ * 
+ * Helper related to {@link EFSUtil}
+ * 
+ * @author Jihoon Song{@literal <jihoon80.song@samsung.com>} (S-Core)
+ * 
+ * @see EFSUtil
+ * 
+ */
+public class EFSUtilTest {
+    
+    /**
+     * Property key for URL handler
+     */
+    protected static final String PROP_PKG = "java.protocol.handler.pkgs";
+    
+    protected static final String TEST_PATH = "test";
+    protected static final String TEST_URL = "cp:///" + TEST_PATH;
+    
+    /**
+     * Old property value for URL handler
+     */
+    protected String oldConfig;
+    
+    
+    /**
+     * Set up URL handler and FileSystem before test
+     */
+    @Before
+    public void setUp() {
+        oldConfig = System.getProperty( PROP_PKG );
+        System.setProperty( PROP_PKG, "org.tizen.common.util.url" );
+        
+        // prevent recreation mock-up when called
+        final IFileSystem mockFileSystem = mock(IFileSystem.class);
+        
+        EFSUtil.setFileSystemSurrogate(new Surrogate<IFileSystem>() {
+            @Override
+            public IFileSystem getAdapter() {
+                return mockFileSystem;
+            }
+        });
+    }
+    
+    /**
+     * Restore URL handler after test
+     */
+    @After
+    public void tearDown() {
+        if ( null == oldConfig ) {
+            System.getProperties().remove( PROP_PKG );
+        } else {
+            System.setProperty( PROP_PKG, oldConfig );
+        }
+    }
+    
+    /**
+     * Test {@link EFSUtil#isExistResource(IFileStore)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see EFSUtil#isExistResource(IFileStore)
+     */
+    @Test
+    public void test_isExistResource_IFileStore() throws Exception {
+        // null check
+        IFileStore nullFileStore = null;
+        assertFalse( EFSUtil.isExistResource(nullFileStore) );
+        
+        
+        IFileInfo mockFileInfo = mock( IFileInfo.class );
+        IFileStore mockFileStore = mock( IFileStore.class );
+        when( mockFileStore.fetchInfo() ).thenReturn( mockFileInfo );
+        
+        // true check
+        when( mockFileInfo.exists() ).thenReturn( true );
+        assertTrue( EFSUtil.isExistResource(mockFileStore) );
+        
+        // false check
+        when( mockFileInfo.exists() ).thenReturn( false );
+        assertFalse( EFSUtil.isExistResource(mockFileStore) );
+    }
+    
+    /**
+     * Test {@link EFSUtil#isExistResource(URI)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see EFSUtil#isExistResource(URI)
+     */
+    @Test
+    public void test_isExistResource_URI() throws Exception {
+        // null check
+        final URI nullURI = null;
+        when( EFSUtil.getFileSystem().getStore(nullURI) ).thenReturn( null );
+        assertFalse( EFSUtil.isExistResource(nullURI) );
+        
+        
+        IFileInfo mockFileInfo = mock( IFileInfo.class );
+        IFileStore mockFileStore = mock( IFileStore.class );
+        when( mockFileStore.fetchInfo() ).thenReturn( mockFileInfo );
+        
+        final URI virtualURI = new URL(TEST_URL).toURI();
+        when( EFSUtil.getFileSystem().getStore(virtualURI) ).thenReturn( mockFileStore );
+        
+        // true check
+        when( mockFileInfo.exists() ).thenReturn( true );
+        assertTrue( EFSUtil.isExistResource(virtualURI) );
+        
+        // false check
+        when( mockFileInfo.exists() ).thenReturn( false );
+        assertFalse( EFSUtil.isExistResource(virtualURI) );
+    }
+    
+    /**
+     * Test {@link EFSUtil#isExistResourceWithDialog(Shell, String, String, DialogChoicer, IFileStore)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see EFSUtil#isExistResourceWithDialog(Shell, String, String, DialogChoicer, IFileStore)
+     */
+    @Test
+    public void test_isExistResourceWithDialog() throws Exception {
+        Shell mockShell = mock( Shell.class );
+        IFileStore mockFileStore = mock( IFileStore.class );
+        IFileInfo mockFileInfo = mock (IFileInfo.class );
+        when(mockFileStore.fetchInfo()).thenReturn(mockFileInfo);
+        
+        final Object[][] TEST_CASES = new Object[][] { // [TestCase] [Arguments..., ExpectResult]
+                new Object[] { mockShell, "Title", "Msg", DialogChoicer.Cancel, mockFileStore, true, DialogChoicer.Cancel },
+                new Object[] { mockShell, "Title", "Msg", DialogChoicer.Cancel, mockFileStore, false, DialogChoicer.Cancel },
+                new Object[] { mockShell, "Title", "Msg", DialogChoicer.NoToAll, mockFileStore, true, DialogChoicer.NoToAll },
+                new Object[] { mockShell, "Title", "Msg", DialogChoicer.NoToAll, mockFileStore, false, DialogChoicer.NoToAll },
+                new Object[] { mockShell, "Title", "Msg", DialogChoicer.YesToAll, mockFileStore, true, DialogChoicer.YesToAll },
+                new Object[] { mockShell, "Title", "Msg", DialogChoicer.YesToAll, mockFileStore, false, DialogChoicer.YesToAll },
+                new Object[] { mockShell, "Title", "Msg", DialogChoicer.Yes, mockFileStore, false, DialogChoicer.Yes },
+                new Object[] { mockShell, "Title", "Msg", DialogChoicer.No, mockFileStore, false, DialogChoicer.Yes }
+                // except dialog open scenarios
+        };
+        
+        DialogChoicer existResourceWithDialog = null;
+        
+        for (final Object[] TEST_CASE : TEST_CASES) {
+            final Shell shell = (Shell) TEST_CASE[0];
+            final String title = (String) TEST_CASE[1];
+            final String msg = (String) TEST_CASE[2];
+            final DialogChoicer choicer = (DialogChoicer) TEST_CASE[3];
+            final IFileStore fileStore = (IFileStore) TEST_CASE[4];
+            final boolean exist = (Boolean) TEST_CASE[5];
+            final DialogChoicer expected = (DialogChoicer) TEST_CASE[6];
+            
+            when( mockFileInfo.exists() ).thenReturn(exist);
+            existResourceWithDialog = EFSUtil.isExistResourceWithDialog(
+                    shell, title, msg, choicer, fileStore);
+            assertEquals( shell + ", " + title + ", " + msg + ", " + choicer + ", " +
+                    fileStore.fetchInfo().exists() + " : " + expected, existResourceWithDialog, expected );
+        }
+    }
+    
+    
+    /**
+     * Test {@link EFSUtil#copy(URI, URI, int, IProgressMonitor)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see EFSUtil#copy(URI, URI, int, IProgressMonitor)
+     */
+    @Test
+    public void test_copy() throws Exception {
+        final URI virtualURI = new URL(TEST_URL).toURI();
+        final IProgressMonitor mockMonitor = mock(IProgressMonitor.class);
+        
+        IFileStore mockFileStore = mock( IFileStore.class );
+        when( EFSUtil.getFileSystem().getStore(virtualURI) ).thenReturn( mockFileStore );
+        
+        final Object[][] TEST_CASES = new Object[][] { // [TestCase] [Arguments..., ExpectResult]
+                new Object[] { virtualURI, virtualURI, EFS.OVERWRITE, mockMonitor },
+                new Object[] { virtualURI, virtualURI, EFS.SHALLOW, mockMonitor },
+                new Object[] { virtualURI, virtualURI, EFS.OVERWRITE | EFS.SHALLOW, mockMonitor }
+        };
+        
+        for (final Object[] TEST_CASE : TEST_CASES) {
+            final URI source = (URI) TEST_CASE[0];
+            final URI destination = (URI) TEST_CASE[1];
+            final int options = (Integer) TEST_CASE[2];
+            final IProgressMonitor monitor = (IProgressMonitor) TEST_CASE[3];
+            
+            EFSUtil.copy(source, destination, options, monitor);
+            
+            verify( mockFileStore ).copy(mockFileStore, options, mockMonitor);
+        }
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/FileUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/FileUtilTest.java
new file mode 100644 (file)
index 0000000..22e7b18
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.junit.Test;
+
+/**
+ * FileUtilTest
+ * 
+ * Test case for {@link FileUtil}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see FileUtil
+ */
+public class FileUtilTest {
+
+       /**
+        * Test {@link FileUtil#getFileExtension(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link FileUtil#getFileExtension(String)}
+        */
+       @Test
+       public void test_getFileExtension() throws Exception {
+               final Object[][] TEST_CASES = new Object[][] {
+                               new Object[] { "aaaa.exe", "exe" },
+                               new Object[] { "index.html", "html" },
+                               new Object[] { "index.test.html", "html" },
+                               new Object[] { "index..html", "html" },
+                               new Object[] { ".profile", "profile" },
+                               new Object[] { "ReadMe ", null },
+                               new Object[] { "ReadMe", null },
+                               new Object[] { "ReadMe. ", " " },
+                               new Object[] { "ReadMe. test", " test" }
+               };
+               
+               int i = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       final String fileName = (String) TEST_CASE[0];
+                       final String expected = (String) TEST_CASE[1];
+                       final String result = FileUtil.getFileExtension( fileName );
+                       
+                       assertEquals( ++i + "th Test case :<" + fileName + ", " + expected + ">", expected, result );
+               }
+       }
+
+    /**
+     * Test {@link FileUtil#readTextStream(InputStream input, String encoding)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link FileUtil#readTextStream(InputStream input, String encoding)}
+     */
+    @Test
+    public void test_readTextStream() throws Exception {
+        String text = "Test Text 123";
+        String unicodeText = "\uD55C\uAE00\uD14C\uC2A4\uD2B8";
+
+        try {
+            FileUtil.readTextStream(null, null);
+            fail( "readTextStream must throw exception" );
+        } catch (Exception e) {
+        }
+
+        InputStream input = new ByteArrayInputStream(text.getBytes());
+        String content = FileUtil.readTextStream(input, null);
+        assertEquals(text, content);
+
+        InputStream unicodeInput = new ByteArrayInputStream(unicodeText.getBytes("UTF-8"));
+        String unicodeContent = FileUtil.readTextStream(unicodeInput, "UTF-8");
+        assertEquals(unicodeText, unicodeContent);
+        String isoContent = FileUtil.readTextStream(unicodeInput, "ISO-8859-1");
+        assertNotSame(unicodeText, isoContent);
+
+        if (input != null) {
+            input.close();
+        }
+        if (unicodeInput != null) {
+            unicodeInput.close();
+        }
+    }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/FilenameUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/FilenameUtilTest.java
new file mode 100644 (file)
index 0000000..42ffdf2
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+
+import org.junit.Test;
+
+
+/**
+ * FilenameUtilTest
+ *
+ * Test case for {@link FilenameUtil}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see FilenameUtil
+ */
+public class
+FilenameUtilTest
+{
+       /**
+        * Test {@link FilenameUtil#getCanonicalFragments(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see FilenameUtil#getCanonicalFragments(String)
+        */
+       @Test
+       public
+       void
+       test_getCanonicalFragments()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { "/aaa/bbb/ccc", new String[] { "aaa", "bbb", "ccc" } },
+                       new Object[] { File.separator + "aaa" + File.separator + "bbb" +  File.separator + "ccc", new String[] { "aaa", "bbb", "ccc" } },
+               };
+               
+               int iTest = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       ++iTest;
+                       final String input = (String) TEST_CASE[0];
+                       final String[] expected = (String[]) TEST_CASE[1];
+                       
+                       assertArrayEquals(
+                               iTest + " th test failed. input :<" + input + ">",
+                               expected,
+                               FilenameUtil.getCanonicalFragments( input )
+                       );
+               }
+       }
+       
+       
+       /**
+        * Test {@link FilenameUtil#addTailingPath(String, String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see FilenameUtil#addTailingPath(String, String)
+        */
+       @Test
+       public
+       void
+       test_addTailingPath()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { "/aaa/bbb/ccc", "aaa", "/aaa/bbb/ccc/aaa" },
+                       new Object[] { "/aaa/bbb/ccc/", "aaa", "/aaa/bbb/ccc/aaa" },
+                       new Object[] { "/aaa/bbb/ccc/", "/aaa", "/aaa/bbb/ccc/aaa" },
+               };
+               
+               int iTest = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       ++iTest;
+                       final String path1 = (String) TEST_CASE[0];
+                       final String path2 = (String) TEST_CASE[1];
+                       final String expected = (String) TEST_CASE[2];
+                       
+                       assertEquals(
+                               iTest + " th test failed. input :<" + path1 + "," + path2 + ">",
+                               expected,
+                               FilenameUtil.addTailingPath( path1, path2 )
+                       );
+               }
+       }
+       
+       /**
+        * Test {@link FilenameUtil#removeTailingPath(String, int)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see FilenameUtil#removeTailingPath(String, int)
+        */
+       @Test
+       public
+       void
+       test_removeTailingPath()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { "/aaa/bbb/ccc", 1, "/aaa/bbb" },
+                       new Object[] { File.separator + "aaa" + File.separator + "bbb" +  File.separator + "ccc", 1, "/aaa/bbb" },
+               };
+               
+               int iTest = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       ++iTest;
+                       final String input = (String) TEST_CASE[0];
+                       final int nRemove = (Integer) TEST_CASE[1];
+                       final String expected = (String) TEST_CASE[2];
+                       
+                       assertEquals(
+                               iTest + " th test failed. input :<" + input + ">",
+                               expected,
+                               FilenameUtil.removeTailingPath( input, nRemove )
+                       );
+               }
+       }
+
+       /**
+        * Test {@link FilenameUtil#getTailingPath(String, int)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see FilenameUtil#getTailingPath(String, int)
+        */
+       @Test
+       public
+       void
+       test_getTailingPath()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { "/aaa/bbb/ccc", 1, "ccc" },
+                       new Object[] { "/aaa/bbb/ccc/", 1, "ccc" },
+                       new Object[] { "/aaa/bbb/ccc", 2, "bbb/ccc" },
+                       new Object[] { File.separator + "aaa" + File.separator + "bbb" +  File.separator + "ccc", 1, "ccc" },
+               };
+               
+               int iTest = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       ++iTest;
+                       final String input = (String) TEST_CASE[0];
+                       final int nRemove = (Integer) TEST_CASE[1];
+                       final String expected = (String) TEST_CASE[2];
+                       
+                       assertEquals(
+                               iTest + " th test failed. input :<" + input + ">",
+                               expected,
+                               FilenameUtil.getTailingPath( input, nRemove )
+                       );
+               }
+       }
+       
+       /**
+        * Test {@link FilenameUtil#getFilename(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see FilenameUtil#getFilename(String)
+        */
+       @Test
+       public
+       void
+       test_getFilename()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { "/aaa/bbb/ccc", "ccc" },
+                       new Object[] { "/aaa/bbb/ccc.jar", "ccc.jar" },
+                       new Object[] { File.separator + "aaa" + File.separator + "bbb" +  File.separator + "ccc", "ccc" },
+               };
+               
+               int iTest = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       ++iTest;
+                       final String input = (String) TEST_CASE[0];
+                       final String expected = (String) TEST_CASE[1];
+                       
+                       assertEquals(
+                               iTest + " th test failed. input :<" + input + ">",
+                               expected,
+                               FilenameUtil.getFilename( input )
+                       );
+               }
+       }
+       
+       /**
+        * Test {@link FilenameUtil#getExtension(String)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see FilenameUtil#getExtension(String)
+        */
+       @Test
+       public
+       void
+       test_getExtension()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { "test.txt", "txt" },
+                       new Object[] { "ccc.jar", "jar" },
+                       new Object[] { ".aaa", "aaa" },
+                       new Object[] { "aaa", "" },
+               };
+               
+               int iTest = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       ++iTest;
+                       final String input = (String) TEST_CASE[0];
+                       final String expected = (String) TEST_CASE[1];
+                       
+                       assertEquals(
+                               iTest + " th test failed. input :<" + input + ">",
+                               expected,
+                               FilenameUtil.getExtension( input )
+                       );
+               }
+       }
+       
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/FilterIteratorTest.java b/org.tizen.common/test/src/org/tizen/common/util/FilterIteratorTest.java
new file mode 100644 (file)
index 0000000..931e4d6
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.junit.Test;
+
+
+/**
+ * FilterIteratorTest
+ *
+ * Test case for {@link FilterIterator}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see FilterIterator
+ */
+public class FilterIteratorTest
+{
+       /**
+        * Test {@link FilterIterator#isAcceptable(Object)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link FilterIterator#isAcceptable(Object)}
+        */
+       @Test
+       public void test_isAcceptable() throws Exception
+       {
+               final ArrayList<String> collection = new ArrayList<String>(
+                       Arrays.asList( "Hello", "World", null )
+               );
+               final FilterIterator<String> iterator = new FilterIterator<String>( collection );
+               
+               assertTrue( iterator.hasNext() );
+               assertEquals( "Hello", iterator.next() );
+               assertTrue( iterator.hasNext() );
+               assertEquals( "World", iterator.next() );
+               assertFalse( iterator.hasNext() );
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/FreeMarkerUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/FreeMarkerUtilTest.java
new file mode 100644 (file)
index 0000000..f1f2772
--- /dev/null
@@ -0,0 +1,62 @@
+package org.tizen.common.util;
+
+import static org.junit.Assert.*;
+
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.junit.Test;
+
+import freemarker.template.Configuration;
+import freemarker.template.DefaultObjectWrapper;
+import freemarker.template.Template;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+
+public class FreeMarkerUtilTest {
+    
+    /**
+     * Test {@link FreeMarkerUtil#getDefaultConfiguration()}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see FreeMarkerUtil#getDefaultConfiguration()
+     */
+    @Test
+    public void test_getDefaultConfiguration() throws Exception {
+        Configuration defaultConfiguration = FreeMarkerUtil.getDefaultConfiguration();
+        
+        String encoding = defaultConfiguration.getEncoding(Locale.getDefault());
+        assertTrue(encoding.equals("8859_1"));
+        
+        assertTrue(defaultConfiguration.getObjectWrapper() instanceof DefaultObjectWrapper);
+    }
+    
+    /**
+     * Test {@link FreeMarkerUtil#generateDocument(Map, Configuration, String, Writer)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see FreeMarkerUtil#generateDocument(Map, Configuration, String, Writer)
+     */
+    @Test
+    public void test_generateDocument() throws Exception {
+        final String templateFile = "zz";
+        final Map<String, Object> root = new HashMap<String, Object>();
+        final Writer mockWriter = mock( Writer.class );
+        
+        final Configuration mockCfg = mock (Configuration.class);
+        final Template mockTemplate = mock( Template.class );
+        when(mockCfg.getTemplate(templateFile)).thenReturn(mockTemplate);
+        
+        FreeMarkerUtil.generateDocument(root, mockCfg, templateFile, mockWriter);
+        verify(mockCfg).getTemplate(templateFile);
+        verify(mockTemplate).process(root, mockWriter);
+        verify(mockWriter).close();
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/HostUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/HostUtilTest.java
new file mode 100644 (file)
index 0000000..1b81a55
--- /dev/null
@@ -0,0 +1,117 @@
+package org.tizen.common.util;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class HostUtilTest {
+
+    private String packageName = HostUtilTest.class.getPackage().getName().replace('.', '/');
+    private String fileName = "test";
+    private String filePath = ClassLoader.getSystemResource(packageName + '/').getPath();
+    private String fullPath = filePath + fileName;
+
+    @Before
+    public void setUp() {
+
+    }
+
+    @After
+    public void tearDown() {
+
+    }
+    
+    /**
+     * Test {@link HostUtil#getContents( String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see HostUtil#getContents( String)
+     */
+    @Test
+    public void test_getContents() throws Exception {
+        Assert.notNull(HostUtil.getContents(fullPath));        
+        Assert.isNull(HostUtil.getContents(null));
+        Assert.isNull(HostUtil.getContents("nullPath"));
+    }
+    
+    /**
+     * Test {@link HostUtil#exists( String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see HostUtil#exists( String)
+     */
+    @Test
+    public void test_exists() throws Exception {
+        Assert.isTrue(HostUtil.exists(fullPath));
+        Assert.isFalse(HostUtil.exists(null));
+        Assert.isFalse(HostUtil.exists("nullPath"));
+    }
+    
+    /**
+     * Test {@link HostUtil#execute( String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see HostUtil#execute( String)
+     */
+    @Test
+    public void test_execute() throws Exception {
+        Assert.isTrue(HostUtil.execute("cd"));
+        Assert.isFalse(HostUtil.execute(null));
+        Assert.isFalse(HostUtil.execute("notcommand"));
+    }
+    
+    /**
+     * Test {@link HostUtil#batchExecute( String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see HostUtil#batchExecute( String)
+     */
+    @Test
+    public void test_batchExecute() throws Exception {
+        Assert.isFalse(HostUtil.batchExecute(null));
+        Assert.isTrue(HostUtil.batchExecute("cd"));
+        Assert.isFalse(HostUtil.batchExecute("notcommand"));
+    }
+    
+    /**
+     * Test {@link HostUtil#returnExecute( String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see HostUtil#returnExecute( String)
+     */
+    @Test
+    public void test_returnExecute1() throws Exception {
+        Assert.isNull(HostUtil.returnExecute(null));
+        Assert.notNull(HostUtil.returnExecute("cd"));
+    }
+    
+    /**
+     * Test {@link HostUtil#returnExecute( String, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see HostUtil#returnExecute( String, String)
+     */
+    @Test
+    public void test_returnExecute2() throws Exception {
+        Assert.isNull(HostUtil.returnExecute(null, filePath));
+        Assert.notNull(HostUtil.returnExecute("cd", filePath));
+    }
+    
+    /**
+     * Test {@link HostUtil#executeWithConsole( String, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see HostUtil#executeWithConsole( String, String)
+     */
+    @Test(expected = Exception.class)
+    public void test_executeWithConsole() throws Exception {
+        HostUtil.executeWithConsole("notcommand", "viewname");        
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/IOUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/IOUtilTest.java
new file mode 100644 (file)
index 0000000..4254e7f
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.Flushable;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import org.junit.Test;
+
+
+/**
+ * IOUtilTest.
+ * 
+ * Test case for {@link IOUtil}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see IOUtil
+ * 
+ */
+public class IOUtilTest
+{
+       /**
+        * Test {@link IOUtil#tryClose(Object...)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link IOUtil#tryClose(Object...)}
+        */
+       @Test
+       public
+       void
+       test_tryClose()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { null },
+                       new Object[] { new Closeable[] { new ByteArrayOutputStream(), new ByteArrayOutputStream() } },
+                       new Object[] { new Closeable[] { null } },
+                       new Object[] { new Closeable[] { null, null, null } },
+                       new Object[] { new Closeable[] { null, new ByteArrayOutputStream() } },
+                       new Object[] { new Closeable[] { new ByteArrayOutputStream(), null } },
+                       new Object[] { new Closeable[] { new ByteArrayOutputStream(), null } },
+                       new Object[] { new Closeable[] { new ByteArrayOutputStream(), null, new ByteArrayOutputStream() } },
+               };
+               
+               int iTestCase = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       ++iTestCase;
+
+                       try
+                       {
+                               IOUtil.tryClose( TEST_CASE[0] );
+                       }
+                       catch ( final Throwable e )
+                       {
+                               fail( iTestCase + " th test case failed" );
+                       }
+               }
+
+               /* Mock Object using Mockito */
+               InputStream in = mock( InputStream.class );
+               IOUtil.tryClose( in );
+               verify( in ).close();
+       }
+
+       /**
+        * Test {@link IOUtil#tryFlush(Flushable...)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link IOUtil#tryFlush(Flushable...)}
+        */
+       @Test
+       public
+       void
+       test_tryFlush()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { null },
+                       new Object[] { new Flushable[] { new ByteArrayOutputStream(), new ByteArrayOutputStream() } },
+                       new Object[] { new Flushable[] { null } },
+                       new Object[] { new Flushable[] { null, null, null } },
+                       new Object[] { new Flushable[] { null, new ByteArrayOutputStream() } },
+                       new Object[] { new Flushable[] { new ByteArrayOutputStream(), null } },
+                       new Object[] { new Flushable[] { new ByteArrayOutputStream(), null } },
+                       new Object[] { new Flushable[] { new ByteArrayOutputStream(), null, new ByteArrayOutputStream() } },
+               };
+               
+               int iTestCase = 0;
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       ++iTestCase;
+                       final Flushable[] flushables = (Flushable[]) TEST_CASE[0];
+
+                       try
+                       {
+                               IOUtil.tryFlush( flushables );
+                       }
+                       catch ( final Throwable e )
+                       {
+                               fail( iTestCase + " th test case failed" );
+                       }
+               }
+               
+               /* Mock Object using Mockito */
+               OutputStream out = mock( OutputStream.class );
+               IOUtil.tryFlush( out );
+               verify( out ).flush();
+       }
+       
+
+       /**
+        * Test {@link IOUtil#redirect(InputStream, OutputStream)},
+        * {@link IOUtil#redirect(java.io.Reader, StringBuffer)},
+        * {@link IOUtil#redirect(java.io.Reader, StringBuilder)} 
+        * and {@link IOUtil#redirect(java.io.Reader, java.io.Writer)}
+        * 
+        * @throws Exception in case of failure in test
+        *
+        * @see IOUtil#redirect(InputStream, OutputStream)
+        * @see IOUtil#redirect(java.io.Reader, StringBuffer)
+        * @see IOUtil#redirect(java.io.Reader, StringBuilder)
+        * @see IOUtil#redirect(java.io.Reader, java.io.Writer)
+        */
+       @Test
+       public
+       void
+       test_redirect()
+       throws Exception
+       {
+               final String[] TEST_CASES = new String[] {
+                       "Hello, World",
+               };
+               
+               int iTestCase = 0;
+               for ( final String TEST_CASE : TEST_CASES )
+               {
+                       ++iTestCase;
+
+                       final ByteArrayInputStream in = new ByteArrayInputStream( TEST_CASE.getBytes() );
+                       final ByteArrayOutputStream out = new ByteArrayOutputStream();
+                       IOUtil.redirect( in, out );
+                       assertArrayEquals( iTestCase + " th test case failed :" + TEST_CASE, TEST_CASE.getBytes(), out.toByteArray() );
+
+                       final StringReader reader = new StringReader( TEST_CASE );
+                       final StringWriter writer = new StringWriter();
+                       IOUtil.redirect( reader, writer );
+                       assertEquals( iTestCase + " th test case failed :" + TEST_CASE, TEST_CASE, writer.toString() );
+
+                       final StringReader reader2 = new StringReader( TEST_CASE );
+                       final StringBuilder builder = new StringBuilder();
+                       IOUtil.redirect( reader2, builder );
+                       assertEquals( iTestCase + " th test case failed :" + TEST_CASE, TEST_CASE, builder.toString() );
+
+                       final StringReader reader3 = new StringReader( TEST_CASE );
+                       final StringBuffer buffer = new StringBuffer();
+                       IOUtil.redirect( reader3, buffer );
+                       assertEquals( iTestCase + " th test case failed :" + TEST_CASE, TEST_CASE, buffer.toString() );
+
+               }
+       }
+       
+       /**
+        * Test {@link IOUtil#getBytes(InputStream)}
+        * 
+        * @throws Exception in case of failure in test
+        *
+        * @see IOUtil#getBytes(InputStream)
+        */
+       @Test
+       public
+       void
+       test_getBytes()
+       throws Exception
+       {
+               assertNotNull( IOUtil.getBytes( new ByteArrayInputStream( "Hello".getBytes() ) ) );
+               assertTrue( 0 < IOUtil.getBytes( new ByteArrayInputStream( "Hello".getBytes() ) ).length );
+       }
+       
+       
+       /**
+        * Test {@link IOUtil#getString(java.io.Reader)},
+        * {@link IOUtil#getString(java.io.Reader, boolean)}
+        * 
+        * @throws Exception in case of failure in test
+        *
+        * @see IOUtil#getString(java.io.Reader)
+        * @see IOUtil#getString(java.io.Reader, boolean)
+        */
+       @Test
+       public
+       void
+       test_getString()
+       throws Exception
+       {
+               assertEquals( "", IOUtil.getString( (Reader) null ) );
+               assertEquals( "Hello", IOUtil.getString( new StringReader("Hello" ) ) );
+               
+               assertEquals( "", IOUtil.getString( (StringReader) null, true ) );
+               assertEquals( "Hello", IOUtil.getString( new StringReader("Hello" ), true ) );
+       }
+       
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/ImageUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/ImageUtilTest.java
new file mode 100644 (file)
index 0000000..5894536
--- /dev/null
@@ -0,0 +1,276 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.tizen.common.SurrogateWithArgument;
+
+
+/**
+ * ImageUtilTest
+ *
+ * Test case for {@link ImageUtil}
+ * 
+ * LookAtMe : "SetUp" & "TearDown" pattern for test
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see ImageUtil
+ */
+public class ImageUtilTest
+{
+    /**
+     * Property key for URL handler
+     */
+    protected static final String PROP_PKG = "java.protocol.handler.pkgs";
+    
+    protected static final String TEST_PATH = ImageUtilTest.class.getSimpleName() + ".png";
+    protected static final String TEST_URL = "cp:///" + TEST_PATH;
+    
+    /**
+     * Old property value for URL handler
+     */
+    protected String oldConfig;
+    
+    /**
+     * Set up URL handler before test
+     */
+    @SuppressWarnings("unchecked")
+       @Before
+    public void setUp()
+    {
+        oldConfig = System.getProperty( PROP_PKG );
+        System.setProperty( PROP_PKG, "org.tizen.common.util.url" );
+        
+        ImageUtil.platformSurrogate = mock(SurrogateWithArgument.class);
+        ImageUtil.pluginSurrogate = mock(SurrogateWithArgument.class);
+
+    }
+    
+    /**
+     * Restore URL handler after test
+     */
+    @After
+    public void tearDown()
+    {
+        ImageUtil.pluginSurrogate = null;
+        ImageUtil.platformSurrogate = null;
+
+       if ( null == oldConfig )
+        {
+            System.getProperties().remove( PROP_PKG );
+            return ;
+        }
+        System.setProperty( PROP_PKG, oldConfig );
+    }
+
+    /**
+     * Test {@link ImageUtil#getImageDescriptor(Bundle, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ImageUtil#getImageDescriptor(Bundle, String)
+     */
+    @Test
+    public
+    void
+    test_getImageDescriptor1()
+    throws Exception
+    {
+        final Bundle bundleMockup = mock( Bundle.class );
+        final URL virtualPathUrl = new URL( TEST_URL );
+        
+        when( bundleMockup.getEntry( TEST_PATH ) ).thenReturn( virtualPathUrl );
+        final ImageDescriptor imgDes =
+            ImageUtil.getImageDescriptor( bundleMockup, TEST_PATH );
+        
+        Assert.assertNotNull(imgDes.createImage(false));
+    }
+
+    /**
+     * Test {@link ImageUtil#getImageDescriptor(String, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ImageUtil#getImageDescriptor(String, String)
+     */
+    @Test
+    public void test_getImageDescriptor2() throws Exception {
+        final Bundle bundleMockup = mock( Bundle.class );
+        final URL virtualPathUrl = new URL( TEST_URL );
+        when( bundleMockup.getEntry( TEST_PATH ) ).thenReturn( virtualPathUrl );
+        final String pluginID = "testID";
+        when(ImageUtil.platformSurrogate.getAdapter(pluginID)).thenReturn(bundleMockup);
+        final ImageDescriptor imgDes = ImageUtil.getImageDescriptor(pluginID, TEST_PATH);
+        
+        final Image img = imgDes.createImage(false);
+        
+        Assert.assertNotNull(img);
+    }
+    
+    /**
+     * Test {@link ImageUtil#getImageDescriptor(Plugin, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ImageUtil#getImageDescriptor(Plugin, String)
+     */
+    @Test
+    public void test_getImageDescriptor3() throws Exception {
+        final Bundle bundleMockup = mock( Bundle.class );
+        final URL virtualPathUrl = new URL( TEST_URL );
+        when( bundleMockup.getEntry( TEST_PATH ) ).thenReturn( virtualPathUrl );
+        final Plugin pluginMockup = mock(Plugin.class);
+        when(ImageUtil.pluginSurrogate.getAdapter(pluginMockup)).thenReturn(bundleMockup);
+        final ImageDescriptor imgDes = ImageUtil.getImageDescriptor(pluginMockup, TEST_PATH);
+        final Image img = imgDes.createImage(false);
+        
+        Assert.assertNotNull(img);
+    }
+    
+    /**
+     * Test {@link ImageUtil#getImage(ImageDescriptor)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ImageUtil#getImage(ImageDescriptor)
+     */
+    @Test
+    public void test_getImage1() throws Exception {
+        final ImageDescriptor imgMock = mock(ImageDescriptor.class);
+        
+        ImageUtil.getImage(imgMock);
+        Mockito.verify(imgMock).createImage();
+    }
+    
+    /**
+     * Test {@link ImageUtil#getImageData(ImageDescriptor)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ImageUtil#getImageData(ImageDescriptor)
+     */
+    @Test
+    public void test_getImageData1() throws Exception {
+        final ImageDescriptor imgMock = mock(ImageDescriptor.class);
+        
+        ImageUtil.getImageData(imgMock);
+        Mockito.verify(imgMock).getImageData();
+    }
+    
+    /**
+     * Test {@link ImageUtil#getImage(Plugin, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ImageUtil#getImage(Plugin, String)
+     */
+    @Test
+    public void test_getImage2() throws Exception {
+        final Bundle bundleMockup = mock( Bundle.class );
+        final URL virtualPathUrl = new URL( TEST_URL );
+        when( bundleMockup.getEntry( TEST_PATH ) ).thenReturn( virtualPathUrl );
+        final Plugin pluginMockup = mock(Plugin.class);
+        when(ImageUtil.pluginSurrogate.getAdapter(pluginMockup)).thenReturn(bundleMockup);
+        
+        Image img = ImageUtil.getImage(pluginMockup, TEST_PATH);
+        
+        Assert.assertNotNull(img);
+    }
+    
+    /**
+     * Test {@link ImageUtil#getImageData(Plugin, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ImageUtil#getImageData(Plugin, String)
+     */
+    @Test
+    public void test_getImageData2() throws Exception {
+        final Bundle bundleMockup = mock( Bundle.class );
+        final URL virtualPathUrl = new URL( TEST_URL );
+        when( bundleMockup.getEntry( TEST_PATH ) ).thenReturn( virtualPathUrl );
+        final Plugin pluginMockup = mock(Plugin.class);
+        when(ImageUtil.pluginSurrogate.getAdapter(pluginMockup)).thenReturn(bundleMockup);
+        
+        ImageData imgData = ImageUtil.getImageData(pluginMockup, TEST_PATH);
+
+        Assert.assertNotNull( imgData );
+    }
+    
+    /**
+     * Test {@link ImageUtil#getImage(String, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ImageUtil#getImage(String, String)
+     */
+    @Test
+    public void test_getImage3() throws Exception {
+        final String pluginID = "testID";
+        final Bundle bundleMockup = mock( Bundle.class );
+        final URL virtualPathUrl = new URL( TEST_URL );
+        when( bundleMockup.getEntry( TEST_PATH ) ).thenReturn( virtualPathUrl );
+        when(ImageUtil.platformSurrogate.getAdapter(pluginID)).thenReturn(bundleMockup);
+        
+        Image img = ImageUtil.getImage(pluginID, TEST_PATH);
+        
+        Assert.assertNotNull(img);
+    }
+    
+    /**
+     * Test {@link ImageUtil#getImageData(String, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ImageUtil#getImageData(String, String)
+     */
+    @Test
+    public void test_getImageData3() throws Exception {
+        final String pluginID = "testID";
+        final Bundle bundleMockup = mock( Bundle.class );
+        final URL virtualPathUrl = new URL( TEST_URL );
+        when( bundleMockup.getEntry( TEST_PATH ) ).thenReturn( virtualPathUrl );
+        when(ImageUtil.platformSurrogate.getAdapter(pluginID)).thenReturn(bundleMockup);
+        
+        ImageData imgData = ImageUtil.getImageData(pluginID, TEST_PATH);
+        Assert.assertNotNull( imgData );
+    }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/ImageUtilTest.png b/org.tizen.common/test/src/org/tizen/common/util/ImageUtilTest.png
new file mode 100644 (file)
index 0000000..d703284
Binary files /dev/null and b/org.tizen.common/test/src/org/tizen/common/util/ImageUtilTest.png differ
diff --git a/org.tizen.common/test/src/org/tizen/common/util/LocalPortCheckerTest.java b/org.tizen.common/test/src/org/tizen/common/util/LocalPortCheckerTest.java
new file mode 100644 (file)
index 0000000..549e8e7
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Random;
+
+import org.junit.Test;
+
+
+/**
+ * LocalPortCheckerTest
+ *
+ * Test case for {@link LocalPortChecker}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see LocalPortChecker
+ */
+public class LocalPortCheckerTest
+{
+       
+       /**
+        * Test {@link LocalPortChecker#isPortInRange(int)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see LocalPortChecker#isPortInRange(int)
+        */
+       @Test
+       public void test_isPortInRange() throws Exception
+       {
+               for ( int i = 0 ; i < 65536 ; ++i )
+               {
+                       assertTrue( LocalPortChecker.isPortInRange( i ) );
+               }
+               assertFalse( LocalPortChecker.isPortInRange( -1 ) );
+               assertFalse( LocalPortChecker.isPortInRange( 65536 ) );
+       }
+       
+       /**
+        * Test {@link LocalPortChecker#isPortAvailable(int)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see LocalPortChecker#isPortAvailable(int)
+        */
+       @Test
+       public void test_isPortAvailable() throws Exception
+       {
+               assertFalse( LocalPortChecker.isPortAvailable( -1 ) );
+               assertTrue( LocalPortChecker.isPortAvailable( 0 ) );
+               assertFalse( LocalPortChecker.isPortAvailable( 65538 ) );
+       }
+       
+       /**
+        * Test {@link LocalPortChecker#getAvailableLocalPort(int, int)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see LocalPortChecker#getAvailableLocalPort(int, int)
+        */
+       @Test
+       public void test_getAvailableLocalPort() throws Exception
+       {
+               final Random r = new Random( System.currentTimeMillis() );
+               final int MIN = 10000;
+               final int MAX = 65535;
+               
+               for ( int i = 0 ; i < 1000 ; ++i )
+               {
+                       final int basePort = r.nextInt( MAX - MIN ) + MIN;
+                       final int inc = r.nextInt( 5 ) - 2;
+
+                       int port = LocalPortChecker.getAvailableLocalPort( inc, basePort );
+                       assertEquals( "base port :" + basePort + ", inc :" + inc + ", real port :" + port, ( basePort == port ), LocalPortChecker.isPortAvailable( basePort ) );
+               }
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/MapUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/MapUtilTest.java
new file mode 100644 (file)
index 0000000..58feb4b
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact:
+* ChangHyun Lee <changhyun1.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.common.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.junit.Test;
+
+
+/**
+ * MapUtilTest.
+ *
+ * Test case for {@link MapUtil}
+ *
+ * @author Changhyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *
+ * @see MapUtil
+ *
+ */
+public class MapUtilTest {
+    /**
+     * Test {@link MapUtil#length(Map)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see MapUtil#length(Map)
+     */
+    @Test
+    public void test_length() throws Exception {
+        assertEquals(0, MapUtil.length(null));
+        Map<String, String> map = new HashMap<String, String>();
+        map.put("aaa", "111");
+        map.put("bbb", "222");
+        assertEquals(map.size(), MapUtil.length(map));
+    }
+
+    /**
+     * Test {@link MapUtil#isEmpty(Map)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see MapUtil#isEmpty(Map)
+     */
+    @Test
+    public void test_isEmpty() throws Exception {
+        assertTrue(MapUtil.isEmpty(null));
+
+        Map<String, String> map = new HashMap<String, String>();
+        assertTrue(MapUtil.isEmpty(map));
+
+        map.put("aaa", "111");
+        map.put("bbb", "222");
+        assertFalse(MapUtil.isEmpty(map));
+    }
+
+    /**
+     * Test {@link MapUtil#asMap(Object[], Object[])
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see MapUtil#asMap(Object[], Object[])
+     */
+    @Test
+    public void test_asMap1() throws Exception {
+        String[] keys = {"aaa", "bbb", "ccc"};
+        String[] values = {"111", "222", "333"};
+        String[] values2 = {"111", "222"};
+
+        assertTrue(MapUtil.asMap(null, null) != null);
+        assertTrue(MapUtil.asMap(keys, null) != null);
+        assertTrue(MapUtil.asMap(null, values) != null);
+
+        Map<String, String> map1 = MapUtil.asMap(keys, values);
+        assertEquals(map1.size(), 3);
+        Map<String, String> map2 = MapUtil.asMap(keys, values2);
+        assertEquals(map2.size(), 2);
+        Map<String, String> map3 = MapUtil.asMap(null, null);
+        assertEquals(map3.size(), 0);
+    }
+
+    /**
+     * Test {@link MapUtil#asMap(Object[][] objs)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link MapUtil#asMap(Object[][] objs)}
+     */
+    @Test
+    public void test_asMap2() throws Exception {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "aaa", "111" },
+            new Object[] { "bbb", "222" },
+        };
+
+        final Object[][] TEST_CASES2 = new Object[][] {
+            new Object[] {"aaa"},
+            new Object[] {null},
+            new Object[] { "aaa", "111" },
+            new Object[] { "bbb", "222" },
+        };
+
+        assertTrue(MapUtil.asMap(null) != null);
+
+        Map<Object, Object> map1 = MapUtil.asMap(TEST_CASES);
+        assertTrue(map1 != null);
+        assertEquals(map1.size(), 2);
+        int iTestCase = 0;
+        for ( final Object[] TEST_CASE : TEST_CASES ) {
+            ++iTestCase;
+            final Object[] object = TEST_CASE;
+            assertEquals(iTestCase + " th test case", object[1], map1.get(object[0]));
+        }
+
+        Map<Object, Object> map2 = MapUtil.asMap(TEST_CASES2);
+        assertTrue(map2 != null);
+        assertEquals(map2.size(), 2);
+    }
+
+    /**
+     * Test {@link MapUtil#mergePropertiesIntoMap(Properties, Map)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see MapUtil#mergePropertiesIntoMap(Properties, Map)
+     */
+    @Test
+    public void test_mergePropertiesIntoMap() throws Exception {
+        Properties properties = new Properties();
+        properties.setProperty("aaa", "111");
+        properties.setProperty("bbb", "222");
+
+        HashMap<Object, Object> map = new HashMap<Object, Object>();
+
+        try {
+            MapUtil.mergePropertiesIntoMap(null, null);
+            fail( "mergePropertiesIntoMap must throw exception" );
+        } catch (Exception e) {
+        }
+
+        try {
+            MapUtil.mergePropertiesIntoMap(properties, null);
+            fail( "mergePropertiesIntoMap must throw exception" );
+        } catch (Exception e) {
+        }
+
+        MapUtil.mergePropertiesIntoMap(null, map);
+
+        assertEquals(map.size(), 0);
+        MapUtil.mergePropertiesIntoMap(properties, map);
+        assertEquals(map.size(), 2);
+        assertEquals(properties.getProperty("aaa"), map.get("aaa"));
+        assertEquals(properties.getProperty("bbb"), map.get("bbb"));
+    }
+
+    /**
+     * Test {@link MapUtil#toString(Map)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see MapUtil#toString(Map)
+     */
+    @Test
+    public void test_toString() throws Exception {
+               final Map<String, String> testTarget = new HashMap<String, String>();
+               testTarget.put( "testKey", "testValue" );
+               
+               final String string = MapUtil.toString( testTarget );
+               
+               assertTrue( string.contains( "testKey" ) );
+               assertTrue( string.contains( "testValue" ) );
+               
+               assertNotNull( MapUtil.toString( null ) );
+       }
+}
@@ -4,7 +4,7 @@
 * 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.
 * - S-Core Co., Ltd
 *
 */
-package org.tizen.common.control;
+package org.tizen.common.util;
 
-public class NotSupportedTypeException extends Exception {
+/**
+ * MockRunner
+ * 
+ * Mock object for {@link Runnable}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ */
+public class
+MockRunner
+implements Runnable
+{
+       
+       boolean bExecute = false;
 
-       public NotSupportedTypeException(){
-               super();
-       }
-       public NotSupportedTypeException(String message){
-               super(message);
+       public void run() {
+               ThreadUtil.trySleep( 50 );
+               bExecute = true;
        }
+
 }
diff --git a/org.tizen.common/test/src/org/tizen/common/util/ObjectUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/ObjectUtilTest.java
new file mode 100644 (file)
index 0000000..23c40ec
--- /dev/null
@@ -0,0 +1,140 @@
+/*\r
+ *  Common\r
+ *\r
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: \r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * TaeYoung son <taeyoung2.son@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.common.util;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+\r
+import org.junit.Test;\r
+\r
+/**\r
+ * ObjectUtilTest.\r
+ * \r
+ * Helper related to {@link ObjectUtil}\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ * @author TaeYoung Son{@literal <taeyoung2.son@samsung.com>} (S-Core)\r
+ * \r
+ * @see ObjectUtil\r
+ * \r
+ */\r
+public class ObjectUtilTest {\r
+    @Test\r
+    public void test_nvl() throws Exception {\r
+        final Object[][] TEST_CASES = new Object[][] {\r
+                new Object[] { null, null },\r
+                new Object[] { new Object[] { null }, null },\r
+                new Object[] { new Object[] { "hello" }, "hello" },\r
+                new Object[] { new Object[] { null, null, "b" }, "b" },\r
+                new Object[] { new Object[] { null, "a", "b" }, "a" } };\r
+\r
+        int nTestCase = 0;\r
+        for (final Object[] TEST_CASE : TEST_CASES) {\r
+            nTestCase++;\r
+            final Object[] input = (Object[]) TEST_CASE[0];\r
+            final Object expected = TEST_CASE[1];\r
+\r
+            assertEquals(nTestCase + "th test case failed." + "\n input : "\r
+                    + input + "\n", expected, ObjectUtil.nvl(input));\r
+        }\r
+    }\r
+\r
+    @Test\r
+    public void test_equals() {\r
+        final Object[][] TEST_CASES = new Object[][] {\r
+                new Object[] { null, null, true },\r
+                new Object[] { null, "a", false },\r
+                new Object[] { "a", null, false },\r
+                new Object[] { "a", "a", true },\r
+                new Object[] { "a", new String("a"), true },\r
+                new Object[] { "a", "b", false },\r
+                new Object[] { new char[] { 'a', 'a', 'b' },\r
+                        new char[] { 'a', 'a', 'b' }, true },\r
+                new Object[] { new int[] { 1, 2, 3 }, new int[] { 1, 3, 2 },\r
+                        false } };\r
+\r
+        int nTestCase = 0;\r
+        for (final Object[] TEST_CASE : TEST_CASES) {\r
+            nTestCase++;\r
+            final Object input1 = (Object) TEST_CASE[0];\r
+            final Object input2 = (Object) TEST_CASE[1];\r
+            final Object expected = TEST_CASE[2];\r
+            assertEquals(nTestCase + "th test case failed."\r
+                    + "\n first input : " + input1 + "\n" + "second input : "\r
+                    + input2 + "\n", expected,\r
+                    ObjectUtil.equals(input1, input2));\r
+        }\r
+    }\r
+\r
+    @Test\r
+    public void test_hexFormat() {\r
+        final Object[][] TEST_CASES = new Object[][] {\r
+                new Object[] { 0, 0, "0" },\r
+                new Object[] { 0, 2, "00" },\r
+                new Object[] { 15, 1, "f" },\r
+                new Object[] { 15, 3, "00f" },\r
+                new Object[] { 2147483647, 10, "007fffffff" },\r
+                new Object[] { -2147483647, 10, "0080000001" },\r
+                new Object[] { -1, 1, "ffffffff" }\r
+        };\r
+\r
+        int nTestCase = 0;\r
+        for (final Object[] TEST_CASE : TEST_CASES) {\r
+            nTestCase++;\r
+            final Object input1 = TEST_CASE[0];\r
+            final Object input2 = TEST_CASE[1];\r
+            final Object expected = TEST_CASE[2];\r
+\r
+            assertEquals(nTestCase + "th test case failed."\r
+                    + "\n first input : " + input1.toString() + "\n" + "second input : "\r
+                    + input2.toString() + "\n", (String)expected,\r
+                    ObjectUtil.hexFormat((Integer)input1, ((Integer)input2).intValue()));\r
+        }\r
+\r
+    }\r
+\r
+    @Test\r
+    public void test_toString() {\r
+        final Object[][] TEST_CASES = new Object[][] {\r
+                new Object[] { null, "<<null>>" },\r
+                new Object[] { "null", "String@C587" },\r
+                new Object[] { "a", "String@0061" },\r
+                new Object[] { "A", "String@0041" },\r
+                new Object[] { 1, "Integer@0001" },\r
+                new Object[] { 10, "Integer@000A" },\r
+                new Object[] { -1, "Integer@FFFF" },\r
+                };\r
+\r
+        int nTestCase = 0;\r
+        for (final Object[] TEST_CASE : TEST_CASES) {\r
+            nTestCase++;\r
+            final Object input = TEST_CASE[0];\r
+            final Object expected = TEST_CASE[1];\r
+\r
+            assertEquals(nTestCase + "th test case failed." + "\n input : "\r
+                    + input + "\n", expected, ObjectUtil.toString(input));\r
+        }\r
+    }\r
+}\r
diff --git a/org.tizen.common/test/src/org/tizen/common/util/ParsingUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/ParsingUtilTest.java
new file mode 100644 (file)
index 0000000..f456715
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ *  Common
+ *
+ * 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.common.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+
+/**
+ * ParsingUtilTest
+ *
+ * Test case for {@link ParsingUtil}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see ParsingUtil
+ */
+public class ParsingUtilTest
+{
+    /**
+     * Test {@link ParsingUtil#parseBoolean(String, boolean)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ParsingUtil#parseBoolean(String, boolean)
+     */
+       @Test
+       public void test_parseBoolean() throws Exception
+       {
+               assertEquals( true, ParsingUtil.parseBoolean( "true", false ) );
+               assertEquals( false, ParsingUtil.parseBoolean( null, false ) );
+               assertEquals( true, ParsingUtil.parseBoolean( null, true ) );
+               assertEquals( false, ParsingUtil.parseBoolean( "xxxx", false ) );
+               assertEquals( true, ParsingUtil.parseBoolean( "xxxx", true ) );
+               assertEquals( true, ParsingUtil.parseBoolean( "Y", false ) );
+               assertEquals( true, ParsingUtil.parseBoolean( "1", false ) );
+       }
+       
+    /**
+     * Test {@link ParsingUtil#parseInt(String, int)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ParsingUtil#parseInt(String, int)
+     */
+       @Test
+       public void test_parseInt() throws Exception
+       {
+               assertEquals( 3, ParsingUtil.parseInt( "3", 0 ) );
+               assertEquals( 2, ParsingUtil.parseInt( "2", 0 ) );
+               assertEquals( 16, ParsingUtil.parseInt( "0x10", 0 ) );
+               assertEquals( 8, ParsingUtil.parseInt( "010", 0 ) );
+       }
+
+    /**
+     * Test {@link ParsingUtil#parseLong(String, long)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ParsingUtil#parseLong(String, long)
+     */
+       @Test
+       public void test_parseLong() throws Exception
+       {
+               assertEquals( 3, ParsingUtil.parseLong( "3", 0 ) );
+               assertEquals( 2, ParsingUtil.parseLong( "2", 0 ) );
+               assertEquals( 16, ParsingUtil.parseLong( "0x10", 0 ) );
+               assertEquals( 8, ParsingUtil.parseLong( "010", 0 ) );
+       }
+
+    /**
+     * Test {@link ParsingUtil#parseDouble(String, double)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see ParsingUtil#parseDouble(String, double)
+     */
+       @Test
+       public void test_parseDouble() throws Exception
+       {
+               assertEquals( 3.0, ParsingUtil.parseDouble( "3", 0 ), 0 );
+               assertEquals( 2.0, ParsingUtil.parseDouble( "2", 0 ), 0 );
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/PluginUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/PluginUtilTest.java
new file mode 100644 (file)
index 0000000..5c1f6ee
--- /dev/null
@@ -0,0 +1,111 @@
+package org.tizen.common.util;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.tizen.common.Surrogate;
+
+/**
+ * PluginUtilTest.
+ *
+ * Test case for {@link PluginUtil}
+ * 
+ * @author Ho Namkoong{@literal <ho.namkoong@samsung.com>} (S-Core)
+ * 
+ * @see PluginUtil
+ */
+public class PluginUtilTest {
+
+    /**
+     * mock up test extension point id
+     */
+    private static final String TEST_EXT_ID = "test-ep";
+    
+    /**
+     * mock up test class id
+     */
+    private static final String TEST_CLS_ID = "test-class";
+    
+    @SuppressWarnings("unchecked")
+    @Before
+    public void setUp() throws Exception {
+        PluginUtil.platformSurrogate = mock(Surrogate.class);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        PluginUtil.platformSurrogate = null;
+    }
+
+    /**
+     * Test {@link PluginUtil#loadClasses(String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see PluginUtil#loadClasses(String)
+     */
+    @Test
+    public void testLoadClasses() throws Exception {
+        
+        final IExtensionRegistry registry = mock(IExtensionRegistry.class);
+        when(PluginUtil.platformSurrogate.getAdapter()).thenReturn(registry);
+        
+        final IExtensionPoint ep = mock(IExtensionPoint.class);
+        when(registry.getExtensionPoint(TEST_EXT_ID)).thenReturn(ep);
+        
+        IExtension[] exts = new IExtension[1];
+        when(ep.getExtensions()).thenReturn(exts);
+        
+        final IExtension ext = mock(IExtension.class);
+        exts[0] = ext;
+        
+        final IConfigurationElement config = mock(IConfigurationElement.class);
+        final IConfigurationElement[] configs = new IConfigurationElement[1];
+        when(ext.getConfigurationElements()).thenReturn(configs);
+        configs[0] = config;
+        
+        PluginUtil.loadClasses(TEST_EXT_ID);
+        Mockito.verify(config).createExecutableExtension("class");
+    }
+
+    /**
+     * Test {@link PluginUtil#loadClass(String, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see PluginUtil#loadClass(String, String)
+     */
+    @Test
+    public void testLoadClass() throws Exception {
+        
+        final IExtensionRegistry registry = mock(IExtensionRegistry.class);
+        when(PluginUtil.platformSurrogate.getAdapter()).thenReturn(registry);
+        
+        final IExtensionPoint ep = mock(IExtensionPoint.class);
+        when(registry.getExtensionPoint(TEST_EXT_ID)).thenReturn(ep);
+        
+        IExtension[] exts = new IExtension[1];
+        when(ep.getExtensions()).thenReturn(exts);
+        
+        final IExtension ext = mock(IExtension.class);
+        exts[0] = ext;
+        
+        final IConfigurationElement config = mock(IConfigurationElement.class);
+        when(config.getAttribute("id")).thenReturn(TEST_CLS_ID);
+        final IConfigurationElement[] configs = new IConfigurationElement[1];
+        when(ext.getConfigurationElements()).thenReturn(configs);
+        configs[0] = config;
+        
+        PluginUtil.loadClass(TEST_EXT_ID, TEST_CLS_ID);
+        Mockito.verify(config).createExecutableExtension("class");
+    }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/SWTUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/SWTUtilTest.java
new file mode 100644 (file)
index 0000000..bf3cce3
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.swt.widgets.Display;
+import org.junit.Test;
+
+
+
+/**
+ * SWTUtilTest.
+ * 
+ * Test case for {@link SWTUtil}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see SWTUtil
+ */
+public class SWTUtilTest
+{
+       /**
+        * Test {@link SWTUtil#getDisplay()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link SWTUtil#getDisplay()}
+        */
+       @Test
+       public void test_getDisplay() throws Exception {
+               Display dp = SWTUtil.getDisplay();
+               assertNotNull( dp );
+               dp.dispose();
+       }
+       
+       /**
+        * Test {@link SWTUtil#asynExec()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link SWTUtil#asynExec()}
+        */
+       @Test
+       public void test_asynExec() throws Exception {
+               MockRunner runnable = new MockRunner();
+               assertFalse( runnable.bExecute );
+               Display dp = SWTUtil.getDisplay();
+               SWTUtil.asyncExec( dp, runnable );
+               assertFalse( runnable.bExecute );
+               
+               long start = System.currentTimeMillis();
+               while ( !runnable.bExecute && (System.currentTimeMillis() - start) < 100 )
+               {
+                       if ( !dp.readAndDispatch() )
+                       {
+                               dp.sleep();
+                       }
+               }
+               assertTrue( runnable.bExecute );
+       }
+       
+       /**
+        * Test {@link SWTUtil#isHtmlFile()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link SWTUtil#isHtmlFile()}
+        */
+       @Test
+       public void test_isHtmlFile() throws Exception {
+               final Object[][] TEST_CASES = new Object[][] {
+                               new Object[] { "aaaa.exe", false },
+                               new Object[] { "index.html", true },
+                               new Object[] { "index.test.html", true },
+                               new Object[] { "index..html", true },
+                               new Object[] { ".profile", false },
+                               new Object[] { "ReadMe ", false },
+                               new Object[] { "ReadMe", false },
+                               new Object[] { "ReadMe. ", false },
+                               new Object[] { "ReadMe. test", false }
+               };
+
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       final String fileName = (String) TEST_CASE[0];
+                       final boolean expected = (Boolean) TEST_CASE[1];
+                       
+                       
+                       /*
+                        * LookAtMe : Attach title when looping test case
+                        */
+                       assertEquals( "input :" + fileName, expected, SWTUtil.isHtmlFile( fileName ) );
+               }
+               
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/StringUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/StringUtilTest.java
new file mode 100644 (file)
index 0000000..e95191c
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * StringUtilTest
+ * 
+ * Test case for {@link StringUtil}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see StringUtil
+ */
+public class
+StringUtilTest
+{
+    /**
+     * @throws Exception in case of failure in test
+     *
+     * @see StringUtil#nvl(String...)
+     */
+    @Test
+    public
+    void
+    test_nvl()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "", new String[] { null, null } },
+            new Object[] { "Hello", new String[] { "Hello", "World" } },
+            new Object[] { "World", new String[] { null, "World" } },
+            new Object[] { "hello", new String[] { null, "hello" } },
+            new Object[] { "hello", new String[] { "hello", "world" } },
+            new Object[] { "hello", new String[] { null, null, "hello", "world" } },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String expected = (String) TEST_CASE[0];
+            final String[] input = (String[]) TEST_CASE[1];
+            assertEquals( expected, StringUtil.nvl( input ) );
+        }
+    }
+
+    /**
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link StringUtil#trimLeadingWhitespace(String)}
+     */
+    @Test
+    public void
+    test_trimLeadingWhitespace()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "", "" },
+            new Object[] { "", "   " },
+            new Object[] { null, null },
+            new Object[] { "Hello", "  Hello" },
+            new Object[] { "H ", " H " },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String expected = (String) TEST_CASE[0];
+            final String input = (String) TEST_CASE[1];
+            assertEquals( expected, StringUtil.trimLeading( input ) );
+        }
+    }
+
+    /**
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link StringUtil#trimLeadingWhitespace(String)}
+     */
+    @Test
+    public void
+    test_trimTrailingWhitespace()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "", "" },
+            new Object[] { "", "   " },
+            new Object[] { null, null },
+            new Object[] { "Hello", "Hello  " },
+            new Object[] { " H", " H " },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String expected = (String) TEST_CASE[0];
+            final String input = (String) TEST_CASE[1];
+            assertEquals( expected, StringUtil.trimTrailing( input ) );
+        }
+    }
+
+    /**
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link StringUtil#trimLeadingCharacter(String, char)}
+     */
+    @Test
+    public void
+    test_trimLeadingCharacter()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "", "", '-' },
+            new Object[] { "   ", "   ", '-' },
+            new Object[] { null, null, '-' },
+            new Object[] { "Hello  ", "---Hello  ", '-' },
+            new Object[] { " H ", " H ", '-' },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String expected = (String) TEST_CASE[0];
+            final String input = (String) TEST_CASE[1];
+            final char trimChar = (Character) TEST_CASE[2];
+            assertEquals(
+                expected,
+                StringUtil.trimLeadingCharacter( input, trimChar )
+            );
+        }
+    }
+
+    /**
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link StringUtil#trimTrailingCharacter(String, char)
+     */
+    @Test
+    public void
+    test_trimTrailingCharacter()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "", "", '-' },
+            new Object[] { "   ", "   ", '-' },
+            new Object[] { null, null, '-' },
+            new Object[] { "Hello", "Hello---", '-' },
+            new Object[] { " H-- ", " H-- ", '-' },
+            new Object[] { " H", " H--", '-' },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String expected = (String) TEST_CASE[0];
+            final String input = (String) TEST_CASE[1];
+            final char trimChar = (Character) TEST_CASE[2];
+            assertEquals(
+                expected,
+                StringUtil.trimTrailingCharacter( input, trimChar )
+            );
+        }
+    }
+
+    /**
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link StringUtil#trimCharacter(String, char)}
+     */
+    @Test
+    public
+    void
+    test_trimCharacter()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "", "", '-' },
+            new Object[] { "   ", "   ", '-' },
+            new Object[] { null, null, '-' },
+            new Object[] { "Hello", "Hello---", '-' },
+            new Object[] { " H-- ", " H-- ", '-' },
+            new Object[] { " H", " H--", '-' },
+            new Object[] { " H", "-- H--", '-' },
+            new Object[] { "H", "--H--", '-' },
+            new Object[] { " - H", "-- - H--", '-' },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String expected = (String) TEST_CASE[0];
+            final String input = (String) TEST_CASE[1];
+            final char trimChar = (Character) TEST_CASE[2];
+            assertEquals(
+                expected,
+                StringUtil.trimCharacter( input, trimChar )
+            );
+        }
+
+    }
+
+    /**
+     * @throws Exception in case of failure in test
+     *
+     * @see StringUtil#getWord(String, int)
+     */
+    @Test
+    public void
+    test_getWord()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "I am a boy", 0, "I" },
+            new Object[] { "I am a boy", 1, "I" },
+            new Object[] { "I am a boy", 2, "am" },
+            new Object[] { "I am a boy", 3, "am" },
+            new Object[] { "I am a boy", 4, "am" },
+            new Object[] { "I am a boy", 5, "a" },
+            new Object[] { "I am a boy", 6, "a" },
+            new Object[] { "I am a boy", 7, "boy" },
+            new Object[] { "I am a boy", 8, "boy" },
+            new Object[] { "I am a boy", 9, "boy" },
+            new Object[] { "I am a boy", 10, "boy" },
+            new Object[] { "I am a boy", 11, "" },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String doc = (String) TEST_CASE[0];
+            final int index = (Integer) TEST_CASE[1];
+            final String expected = (String) TEST_CASE[2];
+            assertEquals(
+                expected,
+                StringUtil.getWord( doc, index )
+            );
+        }
+    }
+
+    /**
+     * @throws Exception in case of failure in test
+     *
+     * @see StringUtil#getPreviousWord(String, int)
+     */
+    @Test
+    public void
+    test_getPreviousWord()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "I am a boy ", 0, "" },
+            new Object[] { "I am a boy ", 1, "I" },
+            new Object[] { "I am a boy ", 2, "" },
+            new Object[] { "I am a boy ", 3, "a" },
+            new Object[] { "I am a boy ", 4, "am" },
+            new Object[] { "I am a boy ", 5, "" },
+            new Object[] { "I am a boy ", 6, "a" },
+            new Object[] { "I am a boy ", 7, "" },
+            new Object[] { "I am a boy ", 8, "b" },
+            new Object[] { "I am a boy ", 9, "bo" },
+            new Object[] { "I am a boy ", 10, "boy" },
+            new Object[] { "I am a boy ", 11, "" },
+            new Object[] { "I am a boy ", 12, "" },
+            new Object[] { "#{\ntest", 2, "#{" },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String doc = (String) TEST_CASE[0];
+            final int index = (Integer) TEST_CASE[1];
+            final String expected = (String) TEST_CASE[2];
+            assertEquals(
+                expected,
+                StringUtil.getPreviousWord( doc, index )
+            );
+        }
+    }
+
+    /**
+     * Test {@link StringUtil#getLastSegment(String, String)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link StringUtil#getLastSegment(String, String)}
+     */
+    @Test
+    public
+    void
+    test_getLastSegement()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { null, " ", "" },
+            new Object[] { "I am a boy", " ", "boy" },
+            new Object[] { "I am a  boy", " ", "boy" },
+            new Object[] { "I am a boy ", " ", "" },
+            new Object[] { "a,b,c,d", ",", "d" },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String doc = (String) TEST_CASE[0];
+            final String separator = (String) TEST_CASE[1];
+            final String expected = (String) TEST_CASE[2];
+            assertEquals(
+                expected,
+                StringUtil.getLastSegment( doc, separator )
+            );
+        }
+    }
+
+    /**
+     * Test {@link StringUtil#getLastSegment(String, String)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link StringUtil#getLastSegment(String, String)}
+     */
+    @Test
+    public
+    void
+    test_removeLastSegement()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { null, " ", "" },
+            new Object[] { "I am a boy", " ", "I am a" },
+            new Object[] { "I am a  boy", " ", "I am a " },        // FIXME ?
+            new Object[] { "I am a boy ", " ", "I am a boy" },
+            new Object[] { "a,b,c,d", ",", "a,b,c" },
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String doc = (String) TEST_CASE[0];
+            final String separator = (String) TEST_CASE[1];
+            final String expected = (String) TEST_CASE[2];
+            assertEquals(
+                expected,
+                StringUtil.removeLastSegment( doc, separator )
+            );
+        }
+    }
+
+    /**
+     * Test {@link StringUtil#split(String, String)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link StringUtil#split(String, String)}
+     */
+    @Test
+    public
+    void
+    test_split()
+    throws Exception
+    {
+        final Object[][] TEST_CASES = new Object[][] {
+            new Object[] { "aa.bbb.ccc", ".", new String[] { "aa", "bbb", "ccc" } }
+        };
+
+        for ( final Object[] TEST_CASE : TEST_CASES )
+        {
+            final String input = (String) TEST_CASE[0];
+            final String delimiters = (String) TEST_CASE[1];
+            final String[] expected = (String[]) TEST_CASE[2];
+
+            assertArrayEquals( expected, StringUtil.split( input, delimiters ) );
+        }
+    }
+
+    /**
+     * Test {@link StringUtil#enumNameToStringArray(T[] values)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link StringUtil#enumNameToStringArray(T[] values)}
+     */
+    @Test
+    public void test_enumNameToStringArray() throws Exception {
+        TestEnumCase [] enums = TestEnumCase.values();
+        String [] values = StringUtil.enumNameToStringArray(enums);
+        assertTrue(enums.length == values.length);
+
+        StringBuilder enumBuilder = new StringBuilder();
+        for (TestEnumCase testEnumCase : enums) {
+            enumBuilder.append(testEnumCase.name());
+        }
+
+        StringBuilder utilBuilder = new StringBuilder();
+        for (String string : values) {
+            utilBuilder.append(string);
+        }
+        assertEquals(enumBuilder.toString(), utilBuilder.toString());
+    }
+
+    /**
+     * Test {@link StringUtil#removeStart(String, String)}
+     * 
+     * @throws Exception in case of failure in test
+     * 
+     * @see {@link StringUtil#removeStart(String, String)}
+     */
+    @Test
+    public void
+    test_removeStart()
+    throws Exception
+    {
+        String str = "abcdefg";
+        String remove1 = "a";
+        String remove2 = "abc";
+        String remove3 = "def";
+
+        // null test
+        assertEquals( str, StringUtil.removeStart( str, null ) );
+        assertEquals( null, StringUtil.removeStart( null, remove1 ) );
+        assertEquals( null, StringUtil.removeStart( null, null ) );
+
+        // start with
+        assertEquals( "bcdefg", StringUtil.removeStart(str, remove1 ) );
+        assertEquals( "defg", StringUtil.removeStart(str, remove2 ) );
+
+        // not start with
+        assertEquals( str, StringUtil.removeStart(str, remove3 ) );
+    }
+
+    public enum TestEnumCase {
+        ABC("ABC"),
+        DEF("DEF"),
+        GHI("GHI"),
+        JKL("JKL");
+        private String value;
+        TestEnumCase(String v) {
+            value = v;
+        }
+        public String value() {
+            return value;
+        }
+    }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/ThreadUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/ThreadUtilTest.java
new file mode 100644 (file)
index 0000000..62f8916
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+*  Common
+*
+* 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.common.util;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+
+/**
+ * ThreadUtilTest
+ * 
+ * Test case for {@link ThreadUtil}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see ThreadUtil
+ */
+public class ThreadUtilTest {
+       
+       /**
+        * Test {@link ThreadUtil#trySleep(long)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link ThreadUtil#trySleep(long)}
+        */
+       @Test
+       public void test_trySleep() throws Exception {
+               final Object[][] TEST_CASES = new Object[][] {
+                               new Object[] { 100, 100 },
+                               new Object[] { 0, 0 },
+                               new Object[] { -100, 0 }
+               };
+               
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       final int milliseconds = (Integer) TEST_CASE[0];
+                       final int expected = (Integer) TEST_CASE[1];
+                       
+                       long start = System.currentTimeMillis();
+                       ThreadUtil.trySleep( milliseconds );
+                       long end = System.currentTimeMillis();
+                       
+                       assertTrue( "input :" + milliseconds + ", expected :" + expected, expected <= ( end - start ) );
+               }
+       }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/ValidationUtilTest.java b/org.tizen.common/test/src/org/tizen/common/util/ValidationUtilTest.java
new file mode 100644 (file)
index 0000000..4fe6bbc
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+*  Common
+*
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+*
+* Contact:
+* ChangHyun Lee <changhyun1.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.common.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * ValidationUtilTest.
+ *
+ * Test case for {@link ValidationUtil}
+ *
+ * @author Changhyun Lee{@literal <changhyun1.lee@samsung.com>} (S-Core)
+ *
+ * @see ValidationUtil
+ *
+ */
+public class ValidationUtilTest {
+
+    /**
+     * Test {@link ValidationUtil#checkForEmail(String value)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link ValidationUtil#checkForEmail(String value)}
+     */
+    @Test
+    public void test_checkForEmail() throws Exception {
+        final String[] validedEmail = {
+                "changhyun1.lee@samsung.com",
+                "12345@exmaple.com",
+                "abcde@exmaple.com",
+                "!a!b#c%d@example.com",
+                "_abcd@example.com",
+                "niceandsimple@example.com",
+                "simplewithsymbol@example.com",
+                "less.common@example.com",
+                "a.little.more.unusual@dept.example.com"
+            };
+        for (String email : validedEmail) {
+            assertTrue(ValidationUtil.checkForEmail(email));
+        }
+
+        final String[] InvalidedEmail = {
+                "changhyun1.lee@samsung",
+                "changhyun1.leesamsung.com",
+                "changhyun1.lee@samsung.com/",
+                "changhyun1.lee@samsung.com!",
+                "@samsung.com",
+                "12345!exmaple.com",
+                "!a!b#c%d@example.co!m",
+                "_abcd@example_com",
+                "user@[IPv6:2001:db8:1ff::a0b:dbd0]",
+                "\"much.more unusual\"@example.com",
+                "\"very.unusual.@.unusual.com\"@example.com",
+                "\"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual\"@strange.example.com",
+                "0@a",
+                "\"!#$%&'*+-/=?^_`{}|~@example.org",
+                "\"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~  ? ^_`{}|~.a\"@example.org",
+                "\"\"@example.org",
+                "postbox@com", // top-level domains are invalid hostnames
+                "Abc.example.com", // an @ character must separate the local and domain parts
+                "Abc.@example.com", // character dot(.) is last in local part
+                "Abc..123@example.com", // character dot(.) is double
+                "A@b@c@example.com ", // only one @ is allowed outside quotation marks
+                "a\"b(c)d,e:f;g<h>i[j\\k]l@example.com", // none of the special characters in this local part is allowed outside quotation marks
+                "just\"not\"right@example.com", // quoted strings must be dot separated, or the only element making up the local-part
+                "this is\"not\\allowed@example.com", // spaces, quotes, and backslashes may only exist when within quoted strings and preceded by a slash
+                "this\\ still\"not\\allowed@example.com" // even if escaped (preceded by a backslash), spaces, quotes, and backslashes must still be contained by quotes
+            };
+        for (String email : InvalidedEmail) {
+            assertFalse(ValidationUtil.checkForEmail(email));
+        }
+    }
+
+    /**
+     * Test {@link ValidationUtil#checkForURL(String value)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link ValidationUtil#checkForURL(String value)}
+     */
+    @Test
+    public void test_checkForURL() throws Exception {
+        final String[] validedURL = {"http://tizen.org", "http://www.tizen.org", "http://tizen.org/", "http://tizen.org/id", "http://myapp"};
+        for (String url : validedURL) {
+            assertTrue(ValidationUtil.checkForURL(url));
+        }
+
+        final String[] invalidedURL = {"http:/tizen.org", "tizen.org", "www.tizen.org", "http://tizen.org/!", "http://tizen.org/id^", "http://tizen.org/id*"};
+        for (String url : invalidedURL) {
+            assertFalse(ValidationUtil.checkForURL(url));
+        }
+    }
+
+    /**
+     * Test {@link ValidationUtil#checkForFileExtension(String value, String[] extensions)}
+     *
+     * @throws Exception in case of failure in test
+     *
+     * @see {@link ValidationUtil#checkForFileExtension(String value, String[] extensions)}
+     */
+    @Test
+    public void test_checkForFileExtension() throws Exception {
+        final String[] extensions = {".html", ".js", ".css"};
+        assertTrue(ValidationUtil.checkForFileExtension("file.html", extensions));
+        assertTrue(ValidationUtil.checkForFileExtension("123.html", extensions));
+        assertTrue(ValidationUtil.checkForFileExtension("file.js", extensions));
+        assertTrue(ValidationUtil.checkForFileExtension("123.js", extensions));
+        assertTrue(ValidationUtil.checkForFileExtension("file.css", extensions));
+        assertTrue(ValidationUtil.checkForFileExtension("123.css", extensions));
+
+        assertFalse(ValidationUtil.checkForFileExtension("file.html1", extensions));
+        assertFalse(ValidationUtil.checkForFileExtension("123.html!", extensions));
+        assertFalse(ValidationUtil.checkForFileExtension("file.jshtml", extensions));
+        assertFalse(ValidationUtil.checkForFileExtension("123.js2", extensions));
+        assertFalse(ValidationUtil.checkForFileExtension("file.aaacss", extensions));
+        assertFalse(ValidationUtil.checkForFileExtension("123.111css", extensions));
+    }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/io/BufferPoolTest.java b/org.tizen.common/test/src/org/tizen/common/util/io/BufferPoolTest.java
new file mode 100644 (file)
index 0000000..ea93b06
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Common
+ *
+ * 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.common.util.io;
+
+import static org.junit.Assert.assertEquals;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+
+import org.junit.Test;
+
+
+/**
+ * BufferPoolTest
+ *
+ * Test case for {@link BufferPool}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see BufferPool
+ */
+public class
+BufferPoolTest
+{
+       /**
+        * Test {@link BufferPool#setSizeOfFragment(int)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link BufferPool#setSizeOfFragment(int)}
+        */
+       @Test
+       public
+       void
+       test_setSizeOfFragment()
+       throws Exception
+       {
+               final ArrayList<ByteBuffer> tempPool = new ArrayList<ByteBuffer>();
+
+               final BufferPool pool = new BufferPool();
+
+               pool.setSizeOfFragment( 10 );
+               pool.setNumberOfFragments( 10 );
+
+               try {
+                       for ( int i = 0 ; i < 9 ; ++i )
+                       {
+                               tempPool.add( pool.borrow() );
+                       }
+                       pool.setSizeOfFragment( 20 );
+                       ByteBuffer buffer = pool.borrow();
+                       assertEquals( 10, buffer.limit() );
+                       tempPool.add( buffer );
+               }
+               finally
+               {
+                       for ( ByteBuffer buffer : tempPool )
+                       {
+                               pool.release( buffer );
+                       }
+                       
+                       tryClose( pool );
+                       
+               }
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/io/BufferTest.java b/org.tizen.common/test/src/org/tizen/common/util/io/BufferTest.java
new file mode 100644 (file)
index 0000000..c5c2c31
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Common
+ *
+ * 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.common.util.io;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * BufferTest
+ *
+ * Test case for {@link Buffer}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see Buffer
+ */
+public class BufferTest
+{
+
+       /**
+        * {@link BufferPool} to use
+        */
+       protected BufferPool bufferPool;
+
+       /**
+        * Set up test unit
+        * 
+        * @throws Exception If test unit can't  be set up
+        */
+       @Before
+       public
+       void
+       setUp()
+       throws Exception
+       {
+               bufferPool = new BufferPool();
+
+               bufferPool.setSizeOfFragment( 10 );
+       }
+
+       /**
+        * Tear down test unit
+        * 
+        * @throws Exception If test unit can't  be tear down
+        */
+       @After
+       public
+       void
+       tearDown()
+       throws Exception
+       {
+               bufferPool.close();
+       }
+
+       /**
+        * Test {@link Buffer#readInt()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Buffer#readInt()}
+        */
+       @Test
+       public
+       void
+       test_readInt()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { 135, new byte[] { 0, 0, 0, -121 } }
+               };
+
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       final int expected = (Integer) TEST_CASE[0];
+                       final byte[] input = (byte[]) TEST_CASE[1];
+                       final Buffer buffer = new Buffer( bufferPool );
+                       try
+                       {
+                               for ( int i = 0, n = input.length ; i < n ; ++i )
+                               {
+                                       buffer.write( input[i] );
+                               }
+
+                               assertEquals( expected, buffer.readInt() );
+                       }
+                       finally
+                       {
+                               tryClose( buffer );
+                       }
+               }
+       }
+
+
+       /**
+        * Test {@link Buffer#writeInt(int)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Buffer#writeInt(int)}
+        */
+       @Test
+       public
+       void
+       test_writeInt()
+       throws Exception
+       {
+               final Object[][] TEST_CASES = new Object[][] {
+                       new Object[] { 135, new int[] { 0, 0, 0, 135 } }
+               };
+
+               for ( final Object[] TEST_CASE : TEST_CASES )
+               {
+                       final int input = (Integer) TEST_CASE[0];
+                       final int[] expected = (int[]) TEST_CASE[1]; 
+
+                       final Buffer buffer = new Buffer( bufferPool );
+                       try
+                       {
+                               buffer.writeInt( input );
+                               for ( int i = 0, n = expected.length ; i < n ; ++i )
+                               {
+                                       assertEquals( expected[i], buffer.read() );
+                               }
+                       }
+                       finally
+                       {
+                               tryClose( buffer );
+                       }
+               }
+       }
+
+       /**
+        * Test {@link Buffer#getBufferSize()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Buffer#getBufferSize()}
+        */
+       @Test
+       public
+       void
+       test_getBufferSize()
+       throws Exception
+       {
+               final Buffer buffer = new Buffer( bufferPool );
+               try
+               {
+                       final BufferOutputStream bufferOut = new BufferOutputStream( buffer );
+                       bufferOut.write( "12345678901234567890123456789012345678901234567890".getBytes() );
+
+                       assertEquals( 5, buffer.getBufferSize() );
+
+                       buffer.read();
+
+                       assertEquals( 5, buffer.getBufferSize() );
+
+               }
+               finally
+               {
+                       tryClose( buffer );
+               }
+
+       }
+
+       /**
+        * Test {@link Buffer#reset()}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Buffer#reset()}
+        */
+       @Test
+       public
+       void
+       test_reset()
+       throws Exception
+       {
+               final byte[] TEST = "12345678901234567890123456789012345678901234567890".getBytes();
+               final Buffer buffer = new Buffer( bufferPool );
+
+               try
+               {
+                       final BufferOutputStream bufferOut = new BufferOutputStream( buffer );
+                       bufferOut.write( TEST );
+
+                       final BufferInputStream bufferIn = new BufferInputStream( buffer );
+                       final byte[] result = new byte[TEST.length];
+
+                       assertEquals( TEST.length, bufferIn.read( result ) );
+                       assertArrayEquals( TEST, result );
+
+                       buffer.reset();
+
+                       assertEquals( TEST.length, bufferIn.read( result ) );
+                       assertArrayEquals( TEST, result );
+               }
+               finally
+               {
+                       tryClose( buffer );
+               }
+
+       }
+
+       /**
+        * Test {@link Buffer#concatenate(Buffer...)}
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Buffer#concatenate(Buffer...)}
+        */
+       @Test
+       public
+       void
+       test_concatenate()
+       throws Exception
+       {
+               final Buffer buffer1 = new Buffer( bufferPool );
+               final Buffer buffer2 = new Buffer( bufferPool );
+
+               final byte[] EXPECTED = "123456789012123456789012".getBytes();
+               final byte[] TEST = "123456789012".getBytes();
+
+               try
+               {
+                       final BufferOutputStream bufferOut1 = new BufferOutputStream( buffer1 );
+                       bufferOut1.write( TEST );
+
+                       final BufferOutputStream bufferOut2 = new BufferOutputStream( buffer1 );
+                       bufferOut2.write( TEST );
+
+                       Buffer ret = Buffer.concatenate( buffer1, buffer2 );
+                       BufferInputStream bufferIn = new BufferInputStream( ret );
+
+                       final byte[] result = new byte[2 * TEST.length];
+
+                       assertEquals( result.length, ret.size() );
+                       assertEquals( result.length, bufferIn.read( result ) );
+                       assertArrayEquals( EXPECTED, result );
+
+               }
+               finally
+               {
+                       tryClose( buffer1 );
+               }
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/test b/org.tizen.common/test/src/org/tizen/common/util/test
new file mode 100644 (file)
index 0000000..9daeafb
--- /dev/null
@@ -0,0 +1 @@
+test
diff --git a/org.tizen.common/test/src/org/tizen/common/util/url/classpath/ConnectionTest.java b/org.tizen.common/test/src/org/tizen/common/util/url/classpath/ConnectionTest.java
new file mode 100644 (file)
index 0000000..38e2701
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+*  Common
+*
+* 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.common.util.url.classpath;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import org.junit.Test;
+
+/**
+ * ConnectionTest
+ *
+ * Test case for {@link Connection}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see Connection
+ */
+public class ConnectionTest
+{
+       /**
+        * Test {@link Connection#getClassLoaders()
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Connection#getClassLoaders()
+        */
+       @Test
+       public
+       void
+       test_getClassLoaders()
+       throws Exception
+       {
+               final Object[] classLoaders = Connection.getClassLoaders().toArray();
+               assertEquals( 1, classLoaders.length );
+               
+               URLClassLoader classLoader = new URLClassLoader( new URL[] {} );
+               Thread.currentThread().setContextClassLoader( classLoader );
+               
+               final Object[] classLoaders2 = Connection.getClassLoaders().toArray();
+               assertEquals( classLoader, classLoaders2[0] );
+               assertEquals( ClassLoader.getSystemClassLoader(), classLoaders2[1] );
+       }
+       
+       /**
+        * Test {@link Connection#getInputStream()
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see Connection#getInputStream()
+        */
+       @Test
+       public void test_getInputStream() throws Exception
+       {
+               final Connection con = new Connection( new URL( "file:///virtualrul" ), null );
+               try
+               {
+                       con.getInputStream();
+                       fail( "Connection must throw IOException" );
+               }
+               catch ( final IOException e )
+               {
+               }
+       }
+
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/url/classpath/HandlerTest.java b/org.tizen.common/test/src/org/tizen/common/util/url/classpath/HandlerTest.java
new file mode 100644 (file)
index 0000000..ba24cb3
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+*  Common
+*
+* 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.common.util.url.classpath;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.tizen.common.util.IOUtil.getBytes;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * HandlerTest
+ *
+ * Test case for {@link Handler}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see Handler
+ */
+public class
+HandlerTest
+{
+       protected String oldConfig;
+       
+       /**
+        * install url handler for classpath
+        */
+       @Before
+       public void setUp()
+       {
+               oldConfig = System.getProperty( "java.protocol.handler.pkgs" );
+               System.setProperty( "java.protocol.handler.pkgs", "org.tizen.common.util.url" );
+       }
+       
+       /**
+        * uninstall url handler for classpath
+        */
+       @After
+       public void tearDown()
+       {
+               if ( null == oldConfig )
+               {
+                       return ;
+               }
+               System.setProperty( "java.protocol.handler.pkgs", oldConfig );
+       }
+       
+       /**
+        * Test {@link Handler#openConnection(URL)
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Handler#openConnection(URL)
+        */
+       @Test
+       public void test_openConnection() throws Exception
+       {
+               
+               final Handler handler = new Handler();
+               final URL url = new URL( "classpath:///" + getClass().getName().replace( '.', '/' ) + ".class" );
+               
+               final URLConnection connection = handler.openConnection( url );
+               
+               connection.connect();
+               InputStream in = connection.getInputStream();
+               try
+               {
+                       assertTrue( 0 < in.read() );
+               }
+               finally
+               {
+                       tryClose( in );
+               }
+               
+               
+       }
+
+       /**
+        * Test {@link Handler#pickupCaller()
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Handler#pickupCaller()
+        */
+       @Test
+       public void test_pickupCaller() throws Exception {
+               final Handler handler = new Handler();
+               assertNull( handler.pickupCaller() );
+               
+               final URL u = new URL( "classpath:///a.txt" );
+               final InputStream in = u.openStream();
+               assertArrayEquals( "Hello, World".getBytes(), getBytes( in, true ) );
+               
+       }
+}
diff --git a/org.tizen.common/test/src/org/tizen/common/util/url/classpath/a.txt b/org.tizen.common/test/src/org/tizen/common/util/url/classpath/a.txt
new file mode 100644 (file)
index 0000000..1856e9b
--- /dev/null
@@ -0,0 +1 @@
+Hello, World
\ No newline at end of file
diff --git a/org.tizen.common/test/src/org/tizen/common/util/url/cp/HandlerTest.java b/org.tizen.common/test/src/org/tizen/common/util/url/cp/HandlerTest.java
new file mode 100644 (file)
index 0000000..34d0a33
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+*  Common
+*
+* 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.common.util.url.cp;
+
+import static org.junit.Assert.assertTrue;
+import static org.tizen.common.util.IOUtil.tryClose;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * HandlerTest
+ *
+ * Test case for {@link Handler}
+ * 
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)
+ * 
+ * @see Handler
+ */
+public class
+HandlerTest
+{
+       /**
+        * Property key for URL handler
+        */
+       protected static final String PROP_PKG = "java.protocol.handler.pkgs";
+       
+       /**
+        * Old property value for URL handler
+        */
+       protected String oldConfig;
+       
+       /**
+        * Set up URL handler before test
+        */
+       @Before
+       public void setUp()
+       {
+               oldConfig = System.getProperty( PROP_PKG );
+               System.setProperty( PROP_PKG, "org.tizen.common.util.url" );
+       }
+       
+       /**
+        * Restore URL handler after test
+        */
+       @After
+       public void tearDown()
+       {
+               if ( null == oldConfig )
+               {
+                       System.getProperties().remove( PROP_PKG );
+                       return ;
+               }
+               System.setProperty( PROP_PKG, oldConfig );
+       }
+       
+       /**
+        * Test {@link Handler#openConnection(URL)
+        * 
+        * @throws Exception in case of failure in test
+        * 
+        * @see {@link Handler#openConnection(URL)
+        */
+       @Test
+       public void test_openConnection() throws Exception
+       {
+               
+               final Handler handler = new Handler();
+               final URL url = new URL( "cp:///" + getClass().getName().replace( '.', '/' ) + ".class" );
+               
+               final URLConnection connection = handler.openConnection( url );
+               
+               connection.connect();
+               InputStream in = connection.getInputStream();
+               try
+               {
+                       assertTrue( 0 < in.read() );
+               }
+               finally
+               {
+                       tryClose( in );
+               }
+               
+               
+       }
+
+}
index 07c4de4..06e3dee 100755 (executable)
-#!/bin/bash -x
-
-build_path=${SRCDIR}/build_result
-
-__set_parameter()
-{
-       build_id=${package_name}
-       build_type=N
-       build_result_directory=${build_type}.${build_id}
-       build_result_path="$build_path/$build_result_directory"
-       architecture=x86
-       ide_root_path_name=IDE
-
-       case ${platform} in
-               linux)
-                       archive_platform_name=linux
-                       windowing=gtk
-                       ;;
-               windows)
-                       archive_platform_name=win32
-                       windowing=win32
-                       ;;
-               *)
-                       echo "${platform} is not support yet."
-                       ;;
-       esac
-
-       result_archive_file=${build_id}-${archive_platform_name}.${windowing}.${architecture}.zip
-}
-
-__set_build_parameter()
-{
-       case ${platform} in
-               linux)
-                       reference_ide_path=${ROOTDIR}/indigo-pde/eclipse
-                       ;;
-               windows)
-                       reference_ide_path=${ROOTDIR}/indigo-winpde/eclipse
-                       ;;
-               *)
-                       echo "${platform} is not support yet."
-                       ;;
-       esac
-}
-
-__set_install_parameter()
-{
-       INSTALL_DIR=${SRCDIR}/package/${package_name}.package.${platform}/data
-}
-
-__clean_build_environment()
-{
-       if [ -d $build_path ]
-       then
-               echo "Build result directory : [$build_path]"
-       else
-               echo "Make build result directory [$build_path]"
-               mkdir -p $build_path
-       fi
-
-       echo "Remove legacy build files..."
-       if [ -d ${build_result_path}/${archive_platform_name}.${windowing}.${architecture} ]
-       then
-               rm -rf ${build_result_path}/${archive_platform_name}.${windowing}.${architecture}
-       fi
-       if [ -e ${build_result_path}/${result_archive_file} ]
-       then
-               rm -rf ${build_result_path}/${result_archive_file}
-       fi
-       if [ -d ${build_path}/tmp ]
-       then
-               rm -rf ${build_path}/tmp
-       fi
-
-       if [ -d ${build_path}/buildRepo ]
-       then
-               rm -rf ${build_path}/buildRepo
-       fi
-
-       rm -r ${build_path}/*.xml
-       rm -r ${build_path}/*.properties
-       rm -r ${build_path}/*.clean
-
-
-       if [ -d $build_path/plugins ]
-       then
-               echo "plugins directory recreate..."
-               rm -rf $build_path/plugins
-               mkdir $build_path/plugins
-       else
-               echo "Make plugins directory..."
-               mkdir $build_path/plugins
-       fi
-       if [ -d $build_path/features/ ]
-       then
-               echo "features directory recreate..."
-               rm -rf $build_path/features
-               mkdir $build_path/features
-       else
-               echo "Make features directory..."
-               mkdir $build_path/features
-       fi
-
-}
-
-__copy_build_sources()
-{
-       echo "Copy features from $SRCDIR to $build_path/features"
-       cp -r $SRCDIR/* $build_path/features
-
-       echo "Copy plugins from $SRCDIR to $build_path/plugins"
-       cp -r $SRCDIR/* $build_path/plugins
-}
-
-__copy_dependency_plugins()
-{
-       dependency_plugin_path=${ROOTDIR}/${ide_root_path_name}
-       if [ -d ${dependency_plugin_path} ]
-       then
-               cp -rf ${dependency_plugin_path}/features/* ${build_path}/features/
-               cp -rf ${dependency_plugin_path}/plugins/* ${build_path}/plugins/
-       fi
-}
-
-__make_ant_build_properties_file()
-{
-       builder_path="${SRCDIR}/builder"
-       parent_path_of_based_eclipse=${reference_ide_path}/..
-
-       echo "Make build.properties file..."
-       if [ ! -e $builder_path/build.properties.clean ] ; then
-               echo "ERROR : \"build.properties.clean\" file does not exist..."
-               exit 1
-       fi
-       cp $builder_path/build.properties.clean $build_path
-       cp $builder_path/customTargets.xml $build_path
-
-       if [ -d $reference_ide_path ] 
-       then
-               sed -e "s;\(^buildDirectory=\).*;\1${build_path};g" \
-               -e "s;\(^base=\).*;\1${parent_path_of_based_eclipse};g" \
-               -e "s;\(^baseLocation=\).*;\1${reference_ide_path};g" \
-               -e "s;\(^configs=\).*;\1${archive_platform_name},${windowing},${architecture};g" \
-               -e "s;\(^buildType=\).*;\1${build_type};g" \
-               -e "s;\(^buildId=\).*;\1${build_id};g" \
-               -e "s;\(^archivePrefix=\).*;\1${build_id};g" \
-               < $build_path/build.properties.clean > $build_path/build.properties
-
-       else
-               echo "ERROR : target eclipse is not exist."
-               exit 1
-       fi
-}
-
-__execute_pde_build()
-{
-       echo "Execute Product Ant Builder..."
-       equinox_launcher=`echo org.eclipse.equinox.launcher_*.jar`
-       pde_build=`echo org.eclipse.pde.build_*`
-
-       java -jar ${reference_ide_path}/plugins/$equinox_launcher -application org.eclipse.ant.core.antRunner -buildfile ${reference_ide_path}/plugins/$pde_build/scripts/productBuild/productBuild.xml -Dbuilder=$build_path -Dosgi.locking=none 2>&1
-
-       if [ $? != 0 ];
-       then
-               echo "Build failed..."
-               exit 1
-       fi
-}
-
-__unzip_plugin_pack()
-{
-       echo "unzip to $build_result_path"
-       unzip -a $build_result_path/${result_archive_file} -d $build_result_path/${archive_platform_name}.${windowing}.${architecture}
-}
-
-build_plugins()
-{
-       case ${platform} in
-               linux)
-                       echo "build plugin for ${platform}"
-                       ;;
-               windows)
-                       echo "build plugin for ${platform}"
-                       ;;
-               *)
-                       echo "${platform} is not support yet."
-                       exit 1
-                       ;;
-       esac
-
-       __set_parameter
-       __set_build_parameter
-       __clean_build_environment
-       __copy_build_sources
-       __copy_dependency_plugins
-       __make_ant_build_properties_file
-       __execute_pde_build
-       __unzip_plugin_pack
-
-       echo "Build SUCCESS. You will find SDK IDE in \"${build_result_path}\"."
-}
-
-__clean_packaging_environment()
-{
-
-       if [ -d ${INSTALL_DIR} ]
-       then
-               rm -rf ${INSTALL_DIR}
-       else
-               mkdir -p ${INSTALL_DIR}
-       fi
-}
+#!/bin/bash -xe
 
 __copy_necessary_binaries()
 {
-       echo "add necessary files."
-       ## ex) cp -rf ~~~~/file.file ${INSTALL_DIR}/${ide_root_path_name}/
+    echo "add necessary files."
+    ## ex)
+    ##     ide_root_path_name=IDE
+    ##     cp -rf ~~~~/file.file ${INSTALL_DIR}/${ide_root_path_name}/
+    ##     cp -rf ${SRCDIR}/packager/common/data/* ${INSTALL_DIR}/
 }
 
-packaging_plugins()
+__set_parameter()
 {
-       __set_parameter
-       __set_install_parameter
-
-       __clean_packaging_environment
-       __copy_necessary_binaries
-
-       install_ide_path=${INSTALL_DIR}/${ide_root_path_name}
-       
-       if [ ! -d ${install_ide_path} ]
-       then
-               mkdir -p ${install_ide_path}
-       fi
-
-       cp -rf ${build_result_path}/${archive_platform_name}.${windowing}.${architecture}/${package_name}/* ${install_ide_path}/
+    echo "TARGET_OS : ${TARGET_OS}"
+    case ${TARGET_OS} in
+        ubuntu-32|ubuntu-64)
+            pde_path=${ROOTDIR}/indigo-pde
+            ;;
+        windows-32|windows-64)
+            pde_path=${ROOTDIR}/indigo-winpde
+            ;;
+        macos-64)
+            pde_path=${ROOTDIR}/indigo-macpde
+            ;;
+        *)
+            echo "${TARGET_OS} is not support yet."
+            exit 1
+            ;;
+    esac
+    
+    build_script_path=${pde_path}/pde_build
 }
 
 # clean
 clean()
 {
-       echo "=========================================CLEAN============================================"
-       make clean
-       rm -rf ${SRCDIR}/*.zip
-       rm -rf ${SRCDIR}/*.tar.gz
-       rm -rf ${build_path}
+    echo "=========================================CLEAN============================================"
+    __set_parameter
+    ${build_script_path}/clean.sh ${package_name}
 }
 
 # build
 build() 
 {
-       echo "=========================================BUILD============================================"
-       pkgname_and_platform_list=`awk 'BEGIN{RS="\n\n"; FS="\n"} /Package:/{for(i=1;i<NF;i++){if($i ~ /^OS:/){print $1,$i}}}' ${SRCDIR}/package/pkginfo.manifest | tr ' ' '@'`
-       for pkgname_and_platform in ${pkgname_and_platform_list}
-       do
-               pkgname_and_platform=`echo $pkgname_and_platform | tr '@' ' '`
-               package_name=`echo ${pkgname_and_platform} | cut -f1 -d " " | cut -f2 -d ":"`
-               platform=`echo ${pkgname_and_platform} | cut -f2 -d " " | cut -f2 -d ":"`
-       
-               if [ "x${BUILD_TARGET_OS}" = "x${platform}" ]
-               then
-                       build_plugins
-               else
-                       echo ""
-               fi
-       done
+    echo "=========================================BUILD============================================"
+    pkgname_and_platform_list=`awk 'BEGIN{RS="\n\n"; FS="\n"} /Package:/{for(i=1;i<NF;i++){if($i ~ /^OS:/){print $1,$i}}}' ${SRCDIR}/package/pkginfo.manifest | tr ' ' '@'`
+    for pkgname_and_platform in ${pkgname_and_platform_list}
+    do
+        pkgname_and_platform=`echo $pkgname_and_platform | tr '@' ' '`
+        package_name=`echo ${pkgname_and_platform} | cut -f1 -d " " | cut -f2 -d ":"`
+        platform=`echo ${pkgname_and_platform} | cut -f2 -d " " | cut -f2 -d ":"`
+    
+        if [ "x${TARGET_OS}" = "x${platform}" ]
+        then
+            __set_parameter
+            ${build_script_path}/build.sh ${package_name}
+       else
+            echo ""
+        fi
+    done
 }
 
 # install
 install() 
 {
-       pkgname_and_platform_list=`awk 'BEGIN{RS="\n\n"; FS="\n"} /Package:/{for(i=1;i<NF;i++){if($i ~ /^OS:/){print $1,$i}}}' ${SRCDIR}/package/pkginfo.manifest | tr ' ' '@'`
-       for pkgname_and_platform in ${pkgname_and_platform_list}
-       do
-               echo "=========================================INSTALL============================================"
-               pkgname_and_platform=`echo $pkgname_and_platform | tr '@' ' '`
-               package_name=`echo ${pkgname_and_platform} | cut -f1 -d " " | cut -f2 -d ":"`
-               platform=`echo ${pkgname_and_platform} | cut -f2 -d " " | cut -f2 -d ":"`
-
-               if [ "x${BUILD_TARGET_OS}" = "x${platform}" ]
-               then
-                       packaging_plugins
-               else
-                       echo ""
-               fi
-       done    
+    pkgname_and_platform_list=`awk 'BEGIN{RS="\n\n"; FS="\n"} /Package:/{for(i=1;i<NF;i++){if($i ~ /^OS:/){print $1,$i}}}' ${SRCDIR}/package/pkginfo.manifest | tr ' ' '@'`
+    for pkgname_and_platform in ${pkgname_and_platform_list}
+    do
+        echo "=========================================INSTALL============================================"
+        pkgname_and_platform=`echo $pkgname_and_platform | tr '@' ' '`
+        package_name=`echo ${pkgname_and_platform} | cut -f1 -d " " | cut -f2 -d ":"`
+        platform=`echo ${pkgname_and_platform} | cut -f2 -d " " | cut -f2 -d ":"`
+
+        if [ "x${TARGET_OS}" = "x${platform}" ]
+        then
+            __set_parameter
+               INSTALL_DIR=${SRCDIR}/package/${package_name}.package.${TARGET_OS}/data
+            mkdir -p ${INSTALL_DIR} 
+            __copy_necessary_binaries
+            ${build_script_path}/install.sh ${package_name}
+        else
+            echo ""
+        fi
+    done    
 }
 
 [ "$1" = "clean" ] && clean
 [ "$1" = "build" ] && build
 [ "$1" = "install" ] && install
-exit 0
index 7f09c0f..9cbbcfe 100644 (file)
@@ -1,19 +1,39 @@
-Package:common-eplugin
-Version:1.0.14
-OS:linux
-Build-host-os:linux
-Build-dependency:indigo-pde [linux], base-ide-product [linux]
-Install-dependency:base-ide-product [linux]
+Version:1.0.64
 Source:common-eplugin
-Maintainer:kangho kim <kh5325.kim@samsung.com>, yoonki park <yoonki.park@samsung.com>, hyunsik non <hyunsik.noh@samsung.com>, taeyoung son <taeyoung2.son@samsung.com>, gune Kim <gune.kim@samsung.com>, ho namkoong <ho.namkoong@samsung.com>, hyeongseok heo <hyeong-seok.heo@samsung.com>, gyeongseok seo <gyeongseok.seo@samsung.com>, jihoon song<jihoon80.song@samsung.com>, changhyun lee <changhyun1.lee@samsung.com>, bonyong lee <bonyong.lee@samsung.com>
+Maintainer:kangho kim <kh5325.kim@samsung.com>, yoonki park <yoonki.park@samsung.com>, hyunsik non <hyunsik.noh@samsung.com>, taeyoung son <taeyoung2.son@samsung.com>, gune Kim <gune.kim@samsung.com>, ho namkoong <ho.namkoong@samsung.com>, hyeongseok heo <hyeong-seok.heo@samsung.com>, gyeongseok seo <gyeongseok.seo@samsung.com>, jihoon song <jihoon80.song@samsung.com>, changhyun lee <changhyun1.lee@samsung.com>, bonyong lee <bonyong.lee@samsung.com>
+
+Package:common-eplugin
+OS:ubuntu-32
+Build-host-os:ubuntu-32
+Build-dependency:indigo-pde [ubuntu-32], base-ide-product [ubuntu-32]
+Install-dependency:base-ide-product [ubuntu-32]
 Description:Common plugin
 
 Package:common-eplugin
-Version:1.0.14
-OS:windows
-Build-host-os:linux
-Build-dependency:indigo-winpde [windows], base-ide-product [windows]
-Install-dependency:base-ide-product [windows]
-Source:common-eplugin
-Maintainer:kangho kim <kh5325.kim@samsung.com>, yoonki park <yoonki.park@samsung.com>, hyunsik non <hyunsik.noh@samsung.com>, taeyoung son <taeyoung2.son@samsung.com>, gune Kim <gune.kim@samsung.com>, ho namkoong <ho.namkoong@samsung.com>, hyeongseok heo <hyeong-seok.heo@samsung.com>, gyeongseok seo <gyeongseok.seo@samsung.com>, jihoon song<jihoon80.song@samsung.com>, changhyun lee <changhyun1.lee@samsung.com>, bonyong lee <bonyong.lee@samsung.com>
+OS:windows-32
+Build-host-os:ubuntu-32
+Build-dependency:indigo-winpde [windows-32], base-ide-product [windows-32]
+Install-dependency:base-ide-product [windows-32]
+Description:Common plugin
+
+Package:common-eplugin
+OS:ubuntu-64
+Build-host-os:ubuntu-64
+Build-dependency:indigo-pde [ubuntu-64], base-ide-product [ubuntu-64]
+Install-dependency:base-ide-product [ubuntu-64]
 Description:Common plugin
+
+Package:common-eplugin
+OS:windows-64
+Build-host-os:ubuntu-64
+Build-dependency:indigo-winpde [windows-64], base-ide-product [windows-64]
+Install-dependency:base-ide-product [windows-64]
+Description:Common plugin
+
+Package:common-eplugin
+OS:macos-64
+Build-host-os:ubuntu-64
+Build-dependency:indigo-macpde [macos-64], base-ide-product [macos-64]
+Install-dependency:base-ide-product [macos-64]
+Description:Common plugin
+