Compare commits
1 Commits
release/5.
...
release/5.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8725877520 |
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0=Der 'BeanPropertyAccessors' der Spalte (mit Überschrift '{0}' und id '{1}') ist nicht korrekt konfiguriert. {2} wird benötigt für die Bean <B>
|
||||
AccessorUtils.Assert1=Der 'BeanPropertyAccessors' der Spalte (mit Überschrift '{0}' und id '{1}') ist nicht korrekt konfiguriert oder der konfigurierte Wert hat nicht den korrekten Typ.
|
||||
AccessorUtils.isReq=\ wird benötigt für die Bean (<B>).
|
||||
AddPushButton.AddButton.Tip=Hinzufügen
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0=\u03A4\u03BF 'BeanPropertyAccessors' \u03C4\u03B7\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B7\u03C2 (\u03BC\u03B5 \u03C4\u03AF\u03C4\u03BB\u03BF '{0}' \u03BA\u03B1\u03B9 \u03B4\u03B9\u03B1\u03BA\u03C1\u03B9\u03C4\u03B9\u03BA\u03CC '{1}') \u03B4\u03B5\u03BD \u03B5\u03AF\u03BD\u03B1\u03B9 \u03C0\u03B1\u03C1\u03B1\u03BC\u03B5\u03C4\u03C1\u03BF\u03C0\u03BF\u03B9\u03B7\u03BC\u03AD\u03BD\u03BF \u03C3\u03C9\u03C3\u03C4\u03AC. \u0391\u03C0\u03B1\u03B9\u03C4\u03B5\u03AF\u03C4\u03B1\u03B9 {2] \u03B3\u03B9\u03B1 \u03C4\u03BF bean <B>
|
||||
AccessorUtils.Assert1=\u03A4\u03BF 'BeanPropertyAccessors' \u03C4\u03B7\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B7\u03C2 (\u03BC\u03B5 \u03C4\u03AF\u03C4\u03BB\u03BF '{0}' \u03BA\u03B1\u03B9 \u03B4\u03B9\u03B1\u03BA\u03C1\u03B9\u03C4\u03B9\u03BA\u03CC '{1}') \u03B4\u03B5\u03BD \u03B5\u03AF\u03BD\u03B1\u03B9 \u03C0\u03B1\u03C1\u03B1\u03BC\u03B5\u03C4\u03C1\u03BF\u03C0\u03BF\u03B9\u03B7\u03BC\u03AD\u03BD\u03BF \u03C3\u03C9\u03C3\u03C4\u03AC \u03AE \u03B7 \u03BF\u03C1\u03B9\u03C3\u03BC\u03AD\u03BD\u03B7 \u03C4\u03B9\u03BC\u03AE \u03B4\u03B5\u03BD \u03B5\u03AF\u03BD\u03B1\u03B9 \u03C4\u03BF\u03C5 \u03C3\u03C9\u03C3\u03C4\u03BF\u03CD \u03C4\u03CD\u03C0\u03BF\u03C5.
|
||||
AddPushButton.AddButton.Tip=\u03A0\u03C1\u03C3\u03B8\u03AE\u03BA\u03B7
|
||||
AddAllPushButton.AddAllButton.Tip=\u03A0\u03C1\u03BF\u03C3\u03B8\u03AE\u03BA\u03B7 \u038C\u03BB\u03C9\u03BD
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0=The 'BeanPropertyAccessors' of the column (with title '{0}' and id '{1}') is not configured correctly. {2} is required for bean <B>
|
||||
AccessorUtils.Assert1=The 'BeanPropertyAccessors' of the column (with title '{0}' and id '{1}') is not configured correctly or the value set has not the correct type.
|
||||
AccessorUtils.NoClassDef=NoClassDefFoundError ({0})\:{1}
|
||||
AccessorUtils.isReq=\ is required for the bean (<B>).
|
||||
@@ -124,3 +123,4 @@ ExceptionMessageDialog.Cancel=Cancel
|
||||
ExceptionMessageDialog.No=No
|
||||
ExceptionMessageDialog.OK=OK
|
||||
ExceptionMessageDialog.Yes=Yes
|
||||
AccessorUtils.Assert0=The 'BeanPropertyAccessors' of the column (with title '{0}' and id '{1}') is not configured correctly. {2} is required for bean <B>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0=La "PropiedadDeAcceso" de la columna (título '{0}' y clave '{1}') no esta correctamente configurada. {2} es requerido para bean <B>
|
||||
AccessorUtils.Assert1=La 'BeanPropertyAccesors' de la columna (con título '{0}' u Id '{0}' no está configurada correctamente o el valor puesto no tiene un tipo adecuado
|
||||
AccessorUtils.isReqValue=es requerido para el valor (<V>), pero éste podría ser adaptado con CellEditorValueAdapter.
|
||||
AddPushButton.AddButton.Tip=Agregue
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0=L'attribut 'BeanPropertyAccessors' de la colonne (nommée '{0}' et ayant l'id '{1}') n'est pas configuré correctement. {2} est requis pour le bean
|
||||
AccessorUtils.Assert1=L'attribut 'BeanPropertyAccessors' de la colonne (nommée'{0}' et ayant l'id '{1}') n'est pas configuré correctement ou le type de la valeur affectée n'est pas correct.
|
||||
AccessorUtils.isReq=\ est requis pour le bean (<B>).
|
||||
AddPushButton.AddButton.Tip=Add
|
||||
@@ -15,7 +14,6 @@ ControlUtils.Unsupported1=Ce contr
|
||||
CopyPushButton.CopyButton.Tip=Copier les éléments sélectionnés
|
||||
DateDialog.textContent=Sélectionner la date et l'heure
|
||||
DefaultCellModifier.tableItemDispose=TableItem effacé
|
||||
DialogErrorForCellEditorListener.Error.MsgDialogTitle=Erreur
|
||||
ErrorDialogWithContinue.setParameter=Définir les paramètres et continuer
|
||||
EventUtil.activate=activer
|
||||
EventUtil.arm=ARM
|
||||
@@ -91,7 +89,6 @@ TableViewerCreator.IdProperty.AssertMsg=Vous devez changer l'idProperty de l'une
|
||||
TableViewerCreator.Table.BeNull=table est null
|
||||
TableViewerCreator.TableColumn.AssertMsg=La TableColumn de TableEditorColumn avec idProperty '{0}' n'a pas la bonne Table parente
|
||||
TreeToTablesLinker.Type.Unsupported=Ce type de currentControl n'est pas supporté
|
||||
commons.error=Erreur
|
||||
exception.errorOccured=Une erreur s'est produite ({0}).\nConsultez le log pour plus de détails.
|
||||
ModelSelectionDialog.BuiltIn=Passer en mode Built-In.
|
||||
ModelSelectionDialog.ViewQuery=Voir la requête (lecture seule).
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0='BeanPropertyAccessors' za stupac (sa naslovom '{0}' i poljem id '{1}') nije ispravno konfiguriran. {2} potreban za bean <B>
|
||||
AccessorUtils.Assert1=BeanPropertyAccessors' za stupac (sa naslovom '{0}' i poljem id '{1}') nije ispravno konfiguriran ili set vrijednosti nije odgovaraju\u0107eg tipa.
|
||||
AddPushButton.AddButton.Tip=Dodaj
|
||||
AddAllPushButton.AddAllButton.Tip=Dodaj sve
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0=La caratteristica 'BeanPropertyAccessors' della colonna (con titolo'{0}' e id '{1}') non sono configurate correttamente. {2} è obbligatorio per il bean.
|
||||
AccessorUtils.Assert1=La caratteristica 'BeanPropertyAccessors' della colonna (titolo '{0}' e id '{1}') non è correttemente configurata o il tipo del valore non è corretto.
|
||||
AddPushButton.AddButton.Tip=Aggiungere
|
||||
AddAllPushButton.AddAllButton.Tip=Aggiungi tutto
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0=\u3053\u306E\u30AB\u30E9\u30E0 (\u30BF\u30A4\u30C8\u30EB '{0}' \u3001id '{1}') \u306E BeanPropertyAccessors \u306F\u6B63\u3057\u304F\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002{2} \u306Fbean <B>\u3067\u8981\u6C42\u3055\u308C\u3066\u3044\u307E\u3059\u3002
|
||||
AccessorUtils.Assert1=\u3053\u306E\u30AB\u30E9\u30E0 (\u30BF\u30A4\u30C8\u30EB '{0}' \u3001id '{1}') \u306E BeanPropertyAccessors \u306F\u6B63\u3057\u304F\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u306A\u3044\u304B\u3001\u5024\u30BB\u30C3\u30C8\u306E\u578B\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093\u3002
|
||||
AccessorUtils.NoClassDef=NoClassDefFoundError({0}):{1}
|
||||
AccessorUtils.isReq=\u306Fbean (<B>) \u3067\u8981\u6C42\u3055\u308C\u307E\u3059\u3002
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0=O 'BeanPropertyAccessors' da coluna (com o título '{0}' e id '{1}') não está configurado corretamente. {2} é requerido para o bean<B>
|
||||
AccessorUtils.Assert1=O «BeanPropertyAccessors' da coluna (com o título '(0)' e id '(1)') não está configurado corretamente ou o valor definido não tem o tipo certo.
|
||||
AddPushButton.AddButton.Tip=Adicionar
|
||||
AddAllPushButton.AddAllButton.Tip=Adicionar todos
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0='BeanPropertyAccessors' \u043A\u043E\u043B\u043E\u043D\u043A\u0438 (\u0441 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u043C '{0}' \u0438 id '{1}') \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E \u0441\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043E\u0432\u0430\u043D. {2} \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E \u0434\u043B\u044F bean <B>
|
||||
AccessorUtils.Assert1='BeanPropertyAccessors' \u043A\u043E\u043B\u043E\u043D\u043A\u0438 (\u0441 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u043C '{0}' \u0438 id '{1}') \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E \u0441\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043E\u0432\u0430\u043D \u0438\u043B\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E\u0433\u043E \u0442\u0438\u043F\u0430
|
||||
AddPushButton.AddButton.Tip=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C
|
||||
AddAllPushButton.AddAllButton.Tip=\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432\u0441\u0435
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AccessorUtils.Assert0=\u8FD9\u4E2A\u5217(\u6807\u9898\u4E3A\u2018{0}\u2019\uFF0CID\u4E3A\u2018{1}\u2019)\u7684\u2018BeanPropertyAccessors\u2019\u6CA1\u6709\u6B63\u786E\u914D\u7F6E\u3002\u2018{2}\u2019\u9700\u8981\u4E00\u4E2ABean<B>
|
||||
AccessorUtils.Assert1=\u8FD9\u4E2A\u5217(\u6807\u9898\u4E3A\u2018{0}\u2019\uFF0CID\u4E3A\u2018{1}\u2019)\u7684\u2018BeanPropertyAccessors\u2019\u6CA1\u6709\u6B63\u786E\u914D\u7F6E,\u6216\u8005\u503C\u8BBE\u7F6E\u4E3A\u4E0D\u6B63\u786E\u7684\u7C7B\u578B\u3002
|
||||
AddPushButton.AddButton.Tip=\u589E\u52A0
|
||||
AddAllPushButton.AddAllButton.Tip=\u6DFB\u52A0\u6240\u6709
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 955 B |
@@ -54,7 +54,6 @@ public enum ECoreImage implements IImage {
|
||||
PROCESS_WIZ("/icons1/process_wiz.png"), //$NON-NLS-1$
|
||||
PROCESS_TEMPLATE_ICON("/icons1/process_icon.gif"), //$NON-NLS-1$
|
||||
PROCESS_TEMPLATE_WIZ("/icons1/process_template_wiz.png"), //$NON-NLS-1$
|
||||
SERVICES_ICON("/icons1/services.png"), //$NON-NLS-1$
|
||||
JOBLET_ICON("/icons1/joblet_icon.png"), //$NON-NLS-1$
|
||||
CONTEXT_ICON("/icons1/context_icon.gif"), //$NON-NLS-1$
|
||||
CONTEXT_CONF_ICON("/icons1/context_conf_icon.gif"), //$NON-NLS-1$
|
||||
@@ -169,7 +168,7 @@ public enum ECoreImage implements IImage {
|
||||
PROGRESSGRAYBAR("/icons1/gray.gif"), //$NON-NLS-1$
|
||||
PROGRESSGRAYGEBAR("/icons1/graygeBar.gif"), //$NON-NLS-1$
|
||||
TRIANGLE("/icons1/triangle.gif"), // triangle.gif //$NON-NLS-1$
|
||||
COMPARE("/icons1/compare.gif"),
|
||||
COMPARE("/icons1/compare.gif"), //$NON-NLS-N$
|
||||
EXCHNAGETAB("/icons/exchangeTab.jpg"), // $NON-NLS-1$
|
||||
EXCHNAGEIMAGEMISSING("/icons/component_missing.gif"); // $NON-NLS-1$
|
||||
|
||||
@@ -188,7 +187,6 @@ public enum ECoreImage implements IImage {
|
||||
*
|
||||
* @return the path
|
||||
*/
|
||||
@Override
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
@@ -198,7 +196,6 @@ public enum ECoreImage implements IImage {
|
||||
*
|
||||
* @return the clazz
|
||||
*/
|
||||
@Override
|
||||
public Class getLocation() {
|
||||
return ECoreImage.class;
|
||||
// return CorePlugin.class;
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.eclipse.jface.viewers.ColumnWeightData;
|
||||
import org.eclipse.jface.viewers.IBaseLabelProvider;
|
||||
import org.eclipse.jface.viewers.ICellModifier;
|
||||
import org.eclipse.jface.viewers.IContentProvider;
|
||||
import org.eclipse.jface.viewers.ILazyContentProvider;
|
||||
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
||||
import org.eclipse.jface.viewers.ITableLabelProvider;
|
||||
import org.eclipse.jface.viewers.TableLayout;
|
||||
@@ -61,7 +60,6 @@ import org.talend.commons.ui.runtime.ws.WindowSystem;
|
||||
import org.talend.commons.ui.swt.tableviewer.behavior.DefaultHeaderColumnSelectionListener;
|
||||
import org.talend.commons.ui.swt.tableviewer.behavior.DefaultStructuredContentProvider;
|
||||
import org.talend.commons.ui.swt.tableviewer.behavior.DefaultTableLabelProvider;
|
||||
import org.talend.commons.ui.swt.tableviewer.behavior.LazyContentProvider;
|
||||
import org.talend.commons.ui.swt.tableviewer.behavior.TableViewerCreatorLayout;
|
||||
import org.talend.commons.ui.swt.tableviewer.data.AccessorUtils;
|
||||
import org.talend.commons.ui.swt.tableviewer.data.ModifiedObjectInfo;
|
||||
@@ -215,15 +213,11 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
|
||||
private boolean columnsSortableByDefault;
|
||||
|
||||
private boolean lazyLoad;
|
||||
|
||||
private ICellModifier cellModifier;
|
||||
|
||||
private ITableLabelProvider labelProvider;
|
||||
|
||||
private IStructuredContentProvider contentProviderold;
|
||||
|
||||
private IContentProvider contentProvider;
|
||||
private IStructuredContentProvider contentProvider;
|
||||
|
||||
private ControlListener tableParentResizedListener;
|
||||
|
||||
@@ -361,7 +355,7 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
tableEditorManager.init(this.listenableList);
|
||||
}
|
||||
|
||||
if (hasChanged && !(contentProvider instanceof ILazyContentProvider)) {
|
||||
if (hasChanged) {
|
||||
refreshTableEditorControls();
|
||||
}
|
||||
|
||||
@@ -431,7 +425,7 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
@Override
|
||||
public void insert(Object element, int position) {
|
||||
super.insert(element, position);
|
||||
refreshTableEditorControls();
|
||||
// tableEditorManager.redrawControls();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -455,10 +449,7 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
@Override
|
||||
public void replace(Object element, int index) {
|
||||
super.replace(element, index);
|
||||
refreshTableEditorColumn(index);
|
||||
if (!(contentProvider instanceof ILazyContentProvider)) {
|
||||
refreshTableEditorControls();
|
||||
}
|
||||
refreshTableEditorControls();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -546,26 +537,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.AbstractTableViewer#inputChanged(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected void inputChanged(Object input, Object oldInput) {
|
||||
if (input instanceof List && contentProvider instanceof ILazyContentProvider) {
|
||||
int newSize = ((List) input).size();
|
||||
int oldSize = 0;
|
||||
if (oldInput instanceof List) {
|
||||
oldSize = ((List) oldInput).size();
|
||||
}
|
||||
if (newSize != oldSize) {
|
||||
tableViewer.setItemCount(newSize);
|
||||
}
|
||||
}
|
||||
super.inputChanged(input, oldInput);
|
||||
}
|
||||
|
||||
};
|
||||
setTablePreferences();
|
||||
|
||||
@@ -591,7 +562,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
if (this.emptyZoneColor != null && !WindowSystem.isGTK() && !WindowSystem.isOSX()) {
|
||||
Listener paintListener = new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
GC gc = event.gc;
|
||||
Rectangle area = table.getClientArea();
|
||||
@@ -612,8 +582,8 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
}
|
||||
TableColumn[] tableColumns = table.getColumns();
|
||||
int widthColumns = 0;
|
||||
for (TableColumn tableColumn : tableColumns) {
|
||||
widthColumns += tableColumn.getWidth();
|
||||
for (int i = 0; i < tableColumns.length; i++) {
|
||||
widthColumns += tableColumns[i].getWidth();
|
||||
}
|
||||
if (widthColumns < area.width) {
|
||||
// System.out.println("widthColumns + 1, 0, area.width, area.height");
|
||||
@@ -666,9 +636,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
if (verticalScroll) {
|
||||
style |= SWT.V_SCROLL;
|
||||
}
|
||||
if (lazyLoad) {
|
||||
style |= SWT.VIRTUAL;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
@@ -680,17 +647,14 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
|
||||
final MouseListener mouseListener = new MouseListener() {
|
||||
|
||||
@Override
|
||||
public void mouseDoubleClick(MouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDown(MouseEvent mouseEvent) {
|
||||
controlClicked = mouseEvent.getSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(MouseEvent e) {
|
||||
|
||||
}
|
||||
@@ -699,7 +663,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
|
||||
final TraverseListener traverseListenerForControls = new TraverseListener() {
|
||||
|
||||
@Override
|
||||
public void keyTraversed(TraverseEvent e) {
|
||||
if (!keyboardManagementForCellEdition) {
|
||||
return;
|
||||
@@ -729,7 +692,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
private void forceTableFocus() {
|
||||
new AsynchronousThreading(10, false, getTable().getDisplay(), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
getTable().forceFocus();
|
||||
}
|
||||
@@ -739,7 +701,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
|
||||
final TraverseListener traverseListenerForTable = new TraverseListener() {
|
||||
|
||||
@Override
|
||||
public void keyTraversed(TraverseEvent e) {
|
||||
if (!keyboardManagementForCellEdition) {
|
||||
return;
|
||||
@@ -759,7 +720,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
|
||||
final KeyListener keyListenerForTable = new KeyListener() {
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (!keyboardManagementForCellEdition) {
|
||||
return;
|
||||
@@ -771,7 +731,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
@@ -780,7 +739,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
|
||||
getTable().addDisposeListener(new DisposeListener() {
|
||||
|
||||
@Override
|
||||
public void widgetDisposed(DisposeEvent e) {
|
||||
if (tableEditorManager != null) {
|
||||
tableEditorManager.release();
|
||||
@@ -793,7 +751,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
if (tableEditorManager != null) {
|
||||
tableEditorManager.addListener(new ITableEditorManagerListener() {
|
||||
|
||||
@Override
|
||||
public void notifyEvent(TableEditorManagerEvent event) {
|
||||
Control editor = event.getTableEditor().getEditor();
|
||||
if (event.getEventType() == EVENT_TYPE.CONTROL_CREATED) {
|
||||
@@ -888,7 +845,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
boolean continueRun = (keyPressed == SWT.TRAVERSE_TAB_NEXT || keyPressed == SWT.TRAVERSE_TAB_PREVIOUS
|
||||
@@ -1021,7 +977,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
|
||||
eraseItemListener = new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
|
||||
// System.out.println(event);
|
||||
@@ -1141,7 +1096,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
if (this.contentProvider == null) {
|
||||
this.contentProvider = new DefaultStructuredContentProvider(this);
|
||||
}
|
||||
|
||||
tableViewer.setContentProvider(this.contentProvider);
|
||||
}
|
||||
|
||||
@@ -1370,7 +1324,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
this.swtStyle = swtStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSwtStyle() {
|
||||
return swtStyle;
|
||||
}
|
||||
@@ -1399,7 +1352,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
this.swtStyle = swtStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSwtStyle() {
|
||||
return swtStyle;
|
||||
}
|
||||
@@ -1618,7 +1570,7 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
return contentProvider;
|
||||
}
|
||||
|
||||
public void setContentProvider(IContentProvider contentProvider) {
|
||||
public void setContentProvider(IStructuredContentProvider contentProvider) {
|
||||
if (tableViewer != null && tableViewer.getContentProvider() != contentProvider) {
|
||||
tableViewer.setContentProvider(contentProvider);
|
||||
}
|
||||
@@ -1790,13 +1742,6 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshTableEditorColumn(int index) {
|
||||
if (tableEditorManager != null && contentProvider instanceof ILazyContentProvider) {
|
||||
tableEditorManager.refreshColumn(index);
|
||||
// tableEditorManager.redrawControls();
|
||||
}
|
||||
}
|
||||
|
||||
public void redrawTableEditorControls() {
|
||||
if (tableEditorManager != null) {
|
||||
tableEditorManager.redrawControls();
|
||||
@@ -2153,13 +2098,4 @@ public class TableViewerCreatorNotModifiable<B> {
|
||||
this.editorActivate = editorActivate;
|
||||
}
|
||||
|
||||
public boolean isLazyLoad() {
|
||||
return this.lazyLoad;
|
||||
}
|
||||
|
||||
public void setLazyLoad(boolean lazyLoad) {
|
||||
this.lazyLoad = lazyLoad;
|
||||
setContentProvider(new LazyContentProvider(this));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,16 +21,14 @@
|
||||
// ============================================================================
|
||||
package org.talend.commons.ui.swt.tableviewer.behavior;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
import org.talend.commons.ui.runtime.image.EImage;
|
||||
import org.talend.commons.ui.runtime.image.ImageProvider;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorColumnNotModifiable;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorNotModifiable;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorColumnNotModifiable;
|
||||
import org.talend.commons.ui.swt.tableviewer.selection.ITableColumnSelectionListener;
|
||||
import org.talend.commons.ui.swt.tableviewer.sort.IColumnSortedListener;
|
||||
import org.talend.commons.utils.data.bean.IBeanPropertyAccessors;
|
||||
|
||||
/**
|
||||
* zhangyi class global comment. Detailled comment <br/>
|
||||
@@ -49,8 +47,7 @@ public class CheckColumnSelectionListener implements ITableColumnSelectionListen
|
||||
/**
|
||||
* zhangyi CheckColumnSelectionListener constructor comment.
|
||||
*/
|
||||
public CheckColumnSelectionListener(TableViewerCreatorColumnNotModifiable tableViewerCreatorColumn,
|
||||
TableViewerCreatorNotModifiable tableViewerCreator) {
|
||||
public CheckColumnSelectionListener(TableViewerCreatorColumnNotModifiable tableViewerCreatorColumn, TableViewerCreatorNotModifiable tableViewerCreator) {
|
||||
this.tableViewerCreatorColumn = tableViewerCreatorColumn;
|
||||
this.tableViewerCreator = tableViewerCreator;
|
||||
this.checked = true;
|
||||
@@ -63,7 +60,6 @@ public class CheckColumnSelectionListener implements ITableColumnSelectionListen
|
||||
* org.talend.commons.ui.swt.tableviewer.selection.ITableColumnSelectionListener#addColumnSortedListener(org.talend
|
||||
* .commons.ui.swt.tableviewer.sort.IColumnSortedListener)
|
||||
*/
|
||||
@Override
|
||||
public void addColumnSortedListener(IColumnSortedListener columnSortedListener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@@ -74,7 +70,6 @@ public class CheckColumnSelectionListener implements ITableColumnSelectionListen
|
||||
*
|
||||
* @see org.talend.commons.ui.swt.tableviewer.selection.ITableColumnSelectionListener#getTableViewerCreator()
|
||||
*/
|
||||
@Override
|
||||
public TableViewerCreatorNotModifiable getTableViewerCreator() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
@@ -85,7 +80,6 @@ public class CheckColumnSelectionListener implements ITableColumnSelectionListen
|
||||
*
|
||||
* @see org.talend.commons.ui.swt.tableviewer.selection.ITableColumnSelectionListener#getTableViewerCreatorColumn()
|
||||
*/
|
||||
@Override
|
||||
public TableViewerCreatorColumnNotModifiable getTableViewerCreatorColumn() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
@@ -98,7 +92,6 @@ public class CheckColumnSelectionListener implements ITableColumnSelectionListen
|
||||
* org.talend.commons.ui.swt.tableviewer.selection.ITableColumnSelectionListener#removeColumnSortedListener(org.
|
||||
* talend.commons.ui.swt.tableviewer.sort.IColumnSortedListener)
|
||||
*/
|
||||
@Override
|
||||
public void removeColumnSortedListener(IColumnSortedListener columnSortedListener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@@ -111,7 +104,6 @@ public class CheckColumnSelectionListener implements ITableColumnSelectionListen
|
||||
* org.talend.commons.ui.swt.tableviewer.selection.ITableColumnSelectionListener#setTableViewerCreator(org.talend
|
||||
* .commons.ui.swt.tableviewer.TableViewerCreator)
|
||||
*/
|
||||
@Override
|
||||
public void setTableViewerCreator(TableViewerCreatorNotModifiable tableViewerCreator) {
|
||||
this.tableViewerCreator = tableViewerCreator;
|
||||
|
||||
@@ -124,7 +116,6 @@ public class CheckColumnSelectionListener implements ITableColumnSelectionListen
|
||||
* org.talend.commons.ui.swt.tableviewer.selection.ITableColumnSelectionListener#setTableViewerCreatorColumn(org
|
||||
* .talend.commons.ui.swt.tableviewer.TableViewerCreatorColumn)
|
||||
*/
|
||||
@Override
|
||||
public void setTableViewerCreatorColumn(TableViewerCreatorColumnNotModifiable tableViewerCreatorColumn) {
|
||||
this.tableViewerCreatorColumn = tableViewerCreatorColumn;
|
||||
}
|
||||
@@ -134,7 +125,6 @@ public class CheckColumnSelectionListener implements ITableColumnSelectionListen
|
||||
*
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@@ -145,48 +135,27 @@ public class CheckColumnSelectionListener implements ITableColumnSelectionListen
|
||||
*
|
||||
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||
*/
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
// if (tableViewerCreator != null && tableViewerCreator.isReadOnly()) {
|
||||
// return;
|
||||
// }
|
||||
// TableItem items[] = tableViewerCreator.getTable().getItems();
|
||||
// String columnId = tableViewerCreatorColumn.getId();
|
||||
// boolean modified = false;
|
||||
// for (TableItem tableItem : items) {
|
||||
// tableViewerCreator.getCellModifier().modify(tableItem, columnId, checked ? false : true);
|
||||
// if (!modified) {
|
||||
// modified = true;
|
||||
// }
|
||||
// }
|
||||
// if (modified) {
|
||||
// if (checked) {
|
||||
// checked = false;
|
||||
// } else {
|
||||
// checked = true;
|
||||
// }
|
||||
// tableViewerCreatorColumn.getTableColumn().setImage(
|
||||
// checked ? ImageProvider.getImage(EImage.CHECKED_ICON) : ImageProvider.getImage(EImage.UNCHECKED_ICON));
|
||||
// }
|
||||
|
||||
if (tableViewerCreator != null && tableViewerCreator.isReadOnly()) {
|
||||
return;
|
||||
}
|
||||
TableItem items[] = tableViewerCreator.getTable().getItems();
|
||||
String columnId = tableViewerCreatorColumn.getId();
|
||||
IBeanPropertyAccessors accessor = tableViewerCreator.getColumn(columnId).getBeanPropertyAccessors();
|
||||
|
||||
List inputList = tableViewerCreator.getInputList();
|
||||
for (int i = 0; i < inputList.size(); i++) {
|
||||
accessor.set(inputList.get(i), checked ? false : true);
|
||||
boolean modified = false;
|
||||
for (TableItem tableItem : items) {
|
||||
tableViewerCreator.getCellModifier().modify(tableItem, columnId, checked ? false : true);
|
||||
if (!modified) {
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (checked) {
|
||||
checked = false;
|
||||
} else {
|
||||
checked = true;
|
||||
if (modified) {
|
||||
if (checked) {
|
||||
checked = false;
|
||||
} else {
|
||||
checked = true;
|
||||
}
|
||||
tableViewerCreatorColumn.getTableColumn().setImage(
|
||||
checked ? ImageProvider.getImage(EImage.CHECKED_ICON) : ImageProvider.getImage(EImage.UNCHECKED_ICON));
|
||||
}
|
||||
tableViewerCreatorColumn.getTableColumn().setImage(
|
||||
checked ? ImageProvider.getImage(EImage.CHECKED_ICON) : ImageProvider.getImage(EImage.UNCHECKED_ICON));
|
||||
tableViewerCreator.refreshTableEditorControls();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ import org.eclipse.jface.viewers.ITableColorProvider;
|
||||
import org.eclipse.jface.viewers.ITableLabelProvider;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorColumnNotModifiable;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorNotModifiable;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorColumnNotModifiable;
|
||||
import org.talend.commons.ui.swt.tableviewer.data.AccessorUtils;
|
||||
|
||||
/**
|
||||
@@ -38,21 +38,19 @@ public class DefaultTableLabelProvider implements ITableLabelProvider, ITableCol
|
||||
this.tableViewerCreator = tableViewerCreator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getColumnImage(Object element, int columnIndex) {
|
||||
TableViewerCreatorColumnNotModifiable column = (TableViewerCreatorColumnNotModifiable) this.tableViewerCreator
|
||||
.getColumns().get(columnIndex);
|
||||
TableViewerCreatorColumnNotModifiable column = (TableViewerCreatorColumnNotModifiable) this.tableViewerCreator.getColumns().get(
|
||||
columnIndex);
|
||||
if (column.getImageProvider() != null) {
|
||||
return column.getImageProvider().getImage(element);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnText(Object element, int columnIndex) {
|
||||
String returnValue = null;
|
||||
TableViewerCreatorColumnNotModifiable column = (TableViewerCreatorColumnNotModifiable) this.tableViewerCreator
|
||||
.getColumns().get(columnIndex);
|
||||
TableViewerCreatorColumnNotModifiable column = (TableViewerCreatorColumnNotModifiable) this.tableViewerCreator.getColumns().get(
|
||||
columnIndex);
|
||||
|
||||
if (column.getLabelProvider() != null) {
|
||||
returnValue = column.getLabelProvider().getLabel(element);
|
||||
@@ -74,15 +72,6 @@ public class DefaultTableLabelProvider implements ITableLabelProvider, ITableCol
|
||||
Object value = AccessorUtils.get(element, column);
|
||||
CellEditor cellEditor = column.getCellEditor();
|
||||
CellEditorValueAdapter retrieverValue = column.getCellEditorValueAdapter();
|
||||
// add for bug TDI-21505
|
||||
if (value != null && column.getCellEditorValueAdapter() != null
|
||||
&& column.getCellEditorValueAdapter() instanceof ComboEditorValueAdapter) {
|
||||
Object returnObject = column.getCellEditorValueAdapter().getCellEditorTypedValue(column.getCellEditor(),
|
||||
value);
|
||||
if ("-1".equals(returnObject + "")) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
if (cellEditor != null && retrieverValue != null && value != null) {
|
||||
returnValue = retrieverValue.getColumnText(cellEditor, element, value);
|
||||
} else if (value != null) {
|
||||
@@ -95,20 +84,16 @@ public class DefaultTableLabelProvider implements ITableLabelProvider, ITableCol
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(ILabelProviderListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLabelProperty(Object element, String property) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(ILabelProviderListener lpl) {
|
||||
}
|
||||
|
||||
@@ -117,10 +102,9 @@ public class DefaultTableLabelProvider implements ITableLabelProvider, ITableCol
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.ITableColorProvider#getBackground(java.lang.Object, int)
|
||||
*/
|
||||
@Override
|
||||
public Color getBackground(Object element, int columnIndex) {
|
||||
TableViewerCreatorColumnNotModifiable column = (TableViewerCreatorColumnNotModifiable) this.tableViewerCreator
|
||||
.getColumns().get(columnIndex);
|
||||
TableViewerCreatorColumnNotModifiable column = (TableViewerCreatorColumnNotModifiable) this.tableViewerCreator.getColumns().get(
|
||||
columnIndex);
|
||||
if (column.getColorProvider() != null) {
|
||||
return column.getColorProvider().getBackgroundColor(element);
|
||||
}
|
||||
@@ -132,10 +116,9 @@ public class DefaultTableLabelProvider implements ITableLabelProvider, ITableCol
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.ITableColorProvider#getForeground(java.lang.Object, int)
|
||||
*/
|
||||
@Override
|
||||
public Color getForeground(Object element, int columnIndex) {
|
||||
TableViewerCreatorColumnNotModifiable column = (TableViewerCreatorColumnNotModifiable) this.tableViewerCreator
|
||||
.getColumns().get(columnIndex);
|
||||
TableViewerCreatorColumnNotModifiable column = (TableViewerCreatorColumnNotModifiable) this.tableViewerCreator.getColumns().get(
|
||||
columnIndex);
|
||||
if (column.getColorProvider() != null) {
|
||||
return column.getColorProvider().getForegroundColor(element);
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.ui.swt.tableviewer.behavior;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.jface.viewers.ILazyContentProvider;
|
||||
import org.eclipse.jface.viewers.TableViewer;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorNotModifiable;
|
||||
|
||||
/**
|
||||
* created by talend2 on 2012-8-24 Detailled comment
|
||||
*
|
||||
*/
|
||||
public class LazyContentProvider implements ILazyContentProvider {
|
||||
|
||||
private TableViewerCreatorNotModifiable tableViewerCreator;
|
||||
|
||||
private Object[] elements;
|
||||
|
||||
public LazyContentProvider(TableViewerCreatorNotModifiable tableViewerCreator) {
|
||||
this.tableViewerCreator = tableViewerCreator;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object,
|
||||
* java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||
if (newInput != null) {
|
||||
elements = ((Collection) newInput).toArray();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.viewers.ILazyContentProvider#updateElement(int)
|
||||
*/
|
||||
@Override
|
||||
public void updateElement(int index) {
|
||||
TableViewer tableViewer = tableViewerCreator.getTableViewer();
|
||||
if (tableViewer.getInput() != null) {
|
||||
elements = ((Collection) tableViewer.getInput()).toArray();
|
||||
}
|
||||
if (elements != null && index < elements.length) {
|
||||
tableViewer.replace(elements[index], index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,8 +39,8 @@ import org.eclipse.swt.widgets.TableColumn;
|
||||
import org.eclipse.swt.widgets.Tree;
|
||||
import org.eclipse.swt.widgets.TreeColumn;
|
||||
import org.talend.commons.ui.runtime.ws.WindowSystem;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorColumnNotModifiable;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorNotModifiable;
|
||||
import org.talend.commons.ui.swt.tableviewer.TableViewerCreatorColumnNotModifiable;
|
||||
import org.talend.commons.ui.utils.threading.AsynchronousThreading;
|
||||
import org.talend.commons.utils.threading.ExecutionLimiter;
|
||||
|
||||
@@ -49,11 +49,10 @@ import org.talend.commons.utils.threading.ExecutionLimiter;
|
||||
*
|
||||
* DefaultTableReflectLayout is based on <code>TableLayout</code> class.
|
||||
*
|
||||
* This supports dynamically resize of columns of table parent composite when you set true <code>continuousLayout</code>
|
||||
* .
|
||||
* This supports dynamically resize of columns of table parent composite when you set true <code>continuousLayout</code>.
|
||||
*
|
||||
* You can now force the layout with the <code>forceLayout</code> method, indeed the current layout method is processed
|
||||
* by default only once time.
|
||||
* You can now force the layout with the <code>forceLayout</code> method, indeed the current layout method is
|
||||
* processed by default only once time.
|
||||
*
|
||||
* $Id: TableViewerCreatorLayout.java 7042 2007-11-15 15:13:48Z smallet $
|
||||
*/
|
||||
@@ -504,8 +503,8 @@ public class TableViewerCreatorLayout extends Layout {
|
||||
/**
|
||||
* Sets if if layout must be really processed at each call or not.
|
||||
*
|
||||
* @param continuousLayout <code>true</code> if layout must be really processed at each call, and <code>false</code>
|
||||
* otherwise
|
||||
* @param continuousLayout <code>true</code> if layout must be really processed at each call, and
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public void setContinuousLayout(boolean continuousLayout) {
|
||||
this.continuousLayout = continuousLayout;
|
||||
@@ -584,10 +583,10 @@ public class TableViewerCreatorLayout extends Layout {
|
||||
if (!WindowSystem.isGTK() && !columnsResizingByLayout && (fillHorizontal || continuousLayout)) {
|
||||
// System.out.println("controlResizedExecute");
|
||||
if (continuousLayout && !fillHorizontal) {
|
||||
// asyncThreadingForManualColumnResizingFalse.interrupt();
|
||||
// if (!fillHorizontal) {
|
||||
// manualResizing = false;
|
||||
// }
|
||||
asyncThreadingForManualColumnResizingFalse.interrupt();
|
||||
if (!fillHorizontal) {
|
||||
manualResizing = false;
|
||||
}
|
||||
}
|
||||
if (!manualResizing) {
|
||||
manualResizing = true;
|
||||
@@ -649,25 +648,7 @@ public class TableViewerCreatorLayout extends Layout {
|
||||
}
|
||||
}
|
||||
if (continuousLayout && !fillHorizontal) {
|
||||
// asyncThreadingForManualColumnResizingFalse.start();
|
||||
Runnable runable = new Runnable() {
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
synchronized (this) {
|
||||
wait(500);
|
||||
manualResizing = false;
|
||||
}
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
manualResizing = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
new Thread(runable).start();
|
||||
|
||||
asyncThreadingForManualColumnResizingFalse.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.collections.set.MapBackedSet;
|
||||
import org.eclipse.jface.viewers.ILazyContentProvider;
|
||||
import org.eclipse.swt.custom.TableEditor;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
@@ -78,7 +77,7 @@ public class TableEditorManager {
|
||||
|
||||
@Override
|
||||
public Collection instanciateNewCollection() {
|
||||
return new ArrayList();
|
||||
return (Collection) new ArrayList();
|
||||
}
|
||||
|
||||
};
|
||||
@@ -108,16 +107,6 @@ public class TableEditorManager {
|
||||
*/
|
||||
public TableEditorManager(TableViewerCreatorNotModifiable tableViewerCreator) {
|
||||
this.tableViewerCreator = tableViewerCreator;
|
||||
columns = tableViewerCreator.getColumns();
|
||||
columnsWithEditorContent = new ArrayList<TableViewerCreatorColumnNotModifiable>(columns.size());
|
||||
|
||||
for (int iCol = 0; iCol < columns.size(); iCol++) {
|
||||
TableViewerCreatorColumnNotModifiable column = columns.get(iCol);
|
||||
TableEditorContentNotModifiable tableEditorContent = column.getTableEditorContent();
|
||||
if (tableEditorContent != null) {
|
||||
columnsWithEditorContent.add(column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -130,7 +119,6 @@ public class TableEditorManager {
|
||||
if (column.getTableColumnSelectionListener() instanceof ITableColumnSelectionListener) {
|
||||
column.getTableColumnSelectionListener().addColumnSortedListener(new IColumnSortedListener() {
|
||||
|
||||
@Override
|
||||
public void handle() {
|
||||
refresh();
|
||||
}
|
||||
@@ -143,7 +131,6 @@ public class TableEditorManager {
|
||||
|
||||
this.listenableListListener = new IListenableListListener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(ListenableListEvent event) {
|
||||
|
||||
if (event.type == TYPE.ADDED) {
|
||||
@@ -182,7 +169,6 @@ public class TableEditorManager {
|
||||
|
||||
new AsynchronousThreading(10, true, compositeParent.getDisplay(), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!compositeParent.isDisposed()) {
|
||||
handleAddedEvent(event);
|
||||
@@ -202,7 +188,6 @@ public class TableEditorManager {
|
||||
|
||||
new AsynchronousThreading(10, true, tableViewerCreator.getCompositeParent().getDisplay(), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!compositeParent.isDisposed()) {
|
||||
handleRemovedEvent(event);
|
||||
@@ -223,44 +208,40 @@ public class TableEditorManager {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(tableViewerCreator.getContentProvider() instanceof ILazyContentProvider)) {
|
||||
TableItem[] items = tableViewerCreator.getTable().getItems();
|
||||
TableItem[] items = tableViewerCreator.getTable().getItems();
|
||||
|
||||
List<TableEditor> addedTableEditor = new ArrayList<TableEditor>();
|
||||
List<TableEditor> addedTableEditor = new ArrayList<TableEditor>();
|
||||
|
||||
for (TableItem item : items) {
|
||||
TableItem tableItem = item;
|
||||
if (previousItemsHash == null || !previousItemsHash.contains(tableItem)) {
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
TableItem tableItem = items[i];
|
||||
if (!previousItemsHash.contains(tableItem)) {
|
||||
|
||||
for (int iEditorCol = 0; iEditorCol < columnsWithEditorContent.size(); iEditorCol++) {
|
||||
TableViewerCreatorColumnNotModifiable column = columnsWithEditorContent.get(iEditorCol);
|
||||
for (int iEditorCol = 0; iEditorCol < columnsWithEditorContent.size(); iEditorCol++) {
|
||||
TableViewerCreatorColumnNotModifiable column = columnsWithEditorContent.get(iEditorCol);
|
||||
|
||||
TableEditorContentNotModifiable tableEditorContent = column.getTableEditorContent();
|
||||
TableEditorContentNotModifiable tableEditorContent = column.getTableEditorContent();
|
||||
|
||||
String idProperty = column.getId();
|
||||
String idProperty = column.getId();
|
||||
|
||||
TableEditor tableEditor = addTableEditor(column, tableEditorContent, idProperty, tableItem);
|
||||
if (tableEditor != null) {
|
||||
addedTableEditor.add(tableEditor);
|
||||
}
|
||||
TableEditor tableEditor = addTableEditor(column, tableEditorContent, idProperty, tableItem);
|
||||
addedTableEditor.add(tableEditor);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = indexStart; i < items.length; i++) {
|
||||
TableItem tableItem = items[i];
|
||||
Object data = tableItem.getData();
|
||||
Collection<TableEditor> tableEditorCollection = dataToMultipleDataEditor.getCollection(data);
|
||||
for (TableEditor tableEditor : tableEditorCollection) {
|
||||
tableEditor.setItem(tableItem);
|
||||
}
|
||||
}
|
||||
|
||||
previousItemsHash = new HashSet<TableItem>(Arrays.asList(items));
|
||||
} else {
|
||||
refreshColumn(indexStart);
|
||||
}
|
||||
|
||||
for (int i = indexStart; i < items.length; i++) {
|
||||
TableItem tableItem = items[i];
|
||||
Object data = tableItem.getData();
|
||||
Collection<TableEditor> tableEditorCollection = (Collection<TableEditor>) dataToMultipleDataEditor
|
||||
.getCollection(data);
|
||||
for (TableEditor tableEditor : tableEditorCollection) {
|
||||
tableEditor.setItem(tableItem);
|
||||
}
|
||||
}
|
||||
|
||||
previousItemsHash = new HashSet<TableItem>(Arrays.asList((TableItem[]) items));
|
||||
|
||||
}
|
||||
|
||||
private void handleRemovedEvent(final ListenableListEvent event) {
|
||||
@@ -305,12 +286,14 @@ public class TableEditorManager {
|
||||
// Warning: using identity comparison
|
||||
// //////////////////////////////////
|
||||
Set dataHash = MapBackedSet.decorate(new IdentityHashMap());
|
||||
dataHash.addAll(Arrays.asList(event.swapedObjects));
|
||||
dataHash.addAll(Arrays.asList((Object[]) event.swapedObjects));
|
||||
;
|
||||
for (TableItem tableItem : items) {
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
TableItem tableItem = items[i];
|
||||
Object data = tableItem.getData();
|
||||
if (dataHash.contains(data)) {
|
||||
Collection<TableEditor> tableEditorCollection = dataToMultipleDataEditor.getCollection(data);
|
||||
Collection<TableEditor> tableEditorCollection = (Collection<TableEditor>) dataToMultipleDataEditor
|
||||
.getCollection(data);
|
||||
for (TableEditor tableEditor : tableEditorCollection) {
|
||||
tableEditor.setItem(tableItem);
|
||||
}
|
||||
@@ -340,7 +323,18 @@ public class TableEditorManager {
|
||||
|
||||
TableItem[] items = table.getItems();
|
||||
|
||||
previousItemsHash = new HashSet<TableItem>(Arrays.asList(items));
|
||||
previousItemsHash = new HashSet<TableItem>(Arrays.asList((TableItem[]) items));
|
||||
|
||||
columns = tableViewerCreator.getColumns();
|
||||
columnsWithEditorContent = new ArrayList<TableViewerCreatorColumnNotModifiable>(columns.size());
|
||||
|
||||
for (int iCol = 0; iCol < columns.size(); iCol++) {
|
||||
TableViewerCreatorColumnNotModifiable column = columns.get(iCol);
|
||||
TableEditorContentNotModifiable tableEditorContent = column.getTableEditorContent();
|
||||
if (tableEditorContent != null) {
|
||||
columnsWithEditorContent.add(column);
|
||||
}
|
||||
}
|
||||
|
||||
for (int iEditorCol = 0; iEditorCol < columnsWithEditorContent.size(); iEditorCol++) {
|
||||
TableViewerCreatorColumnNotModifiable column = columnsWithEditorContent.get(iEditorCol);
|
||||
@@ -349,55 +343,15 @@ public class TableEditorManager {
|
||||
|
||||
String idProperty = column.getId();
|
||||
|
||||
for (TableItem item : items) {
|
||||
addTableEditor(column, tableEditorContent, idProperty, item);
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
addTableEditor(column, tableEditorContent, idProperty, items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void refreshColumn(int index) {
|
||||
Table table = tableViewerCreator.getTable();
|
||||
if (table.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
for (int iEditorCol = 0; iEditorCol < columnsWithEditorContent.size(); iEditorCol++) {
|
||||
TableViewerCreatorColumnNotModifiable column = columnsWithEditorContent.get(iEditorCol);
|
||||
|
||||
TableEditorContentNotModifiable tableEditorContent = column.getTableEditorContent();
|
||||
|
||||
String idProperty = column.getId();
|
||||
|
||||
TableItem tableItem = table.getItems()[index];
|
||||
if (dataToMultipleDataEditor.containsKey(tableItem.getData())) {
|
||||
Collection<TableEditor> object = dataToMultipleDataEditor.getCollection(tableItem.getData());
|
||||
for (TableEditor tableEditor : object) {
|
||||
tableEditor.setItem(tableItem);
|
||||
Control editor = tableEditor.getEditor();
|
||||
if (editor != null) {
|
||||
editor.redraw();
|
||||
}
|
||||
}
|
||||
if (object.size() == columnsWithEditorContent.size()) {
|
||||
break;
|
||||
} else {
|
||||
if (iEditorCol < object.size()) {
|
||||
continue;
|
||||
} else {
|
||||
addTableEditor(column, tableEditorContent, idProperty, table.getItems()[index]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addTableEditor(column, tableEditorContent, idProperty, table.getItems()[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TableEditor addTableEditor(TableViewerCreatorColumnNotModifiable column,
|
||||
TableEditorContentNotModifiable tableEditorContent, String idProperty, TableItem tableItem) {
|
||||
if (tableItem.getData() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
tableEditorContent.setLayoutEnabled(true);
|
||||
TableEditor tableEditor = tableEditorContent.createTableEditor(tableItem.getParent());
|
||||
@@ -405,8 +359,7 @@ public class TableEditorManager {
|
||||
dataToMultipleDataEditor.put(tableItem.getData(), tableEditor);
|
||||
|
||||
Object currentRowObject = tableItem.getData();
|
||||
// Object value = tableViewerCreator.getCellModifier().getValue(currentRowObject, idProperty);
|
||||
Object value = column.getBeanPropertyAccessors().get(tableItem.getData());
|
||||
Object value = tableViewerCreator.getCellModifier().getValue(currentRowObject, idProperty);
|
||||
Control control = tableEditorContent.initialize(tableItem.getParent(), tableEditor, column, currentRowObject, value);
|
||||
|
||||
// control.addDisposeListener(new DisposeListener() {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry exported="true" kind="lib" path="data" sourcepath="data"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
@@ -5,6 +5,4 @@ Bundle-SymbolicName: org.talend.commons.runtime.test
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Fragment-Host: org.talend.commons.runtime
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Require-Bundle: org.junit
|
||||
Bundle-ClassPath: data/,
|
||||
.
|
||||
Require-Bundle: org.junit4
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
data/,\
|
||||
.
|
||||
source.. = src/
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
salut
|
||||
@@ -1,54 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.resource;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* created by scorreia on Jul 3, 2012 Detailled comment
|
||||
*
|
||||
*/
|
||||
public class ResourceUtilTest {
|
||||
|
||||
/**
|
||||
* Test method for {@link org.talend.commons.utils.resource.ResourceUtil#convertResourceToFile(java.net.URL)}.
|
||||
*/
|
||||
@Ignore("This test should be implemented later")
|
||||
@Test
|
||||
public void testConvertResourceToFile() {
|
||||
fail("Not yet implemented"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.talend.commons.utils.resource.ResourceUtil#getFileFromResource(java.lang.Class, java.lang.String)}.
|
||||
*
|
||||
* @throws URISyntaxException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testGetFileFromResource() throws IOException, URISyntaxException {
|
||||
String filename = "/data/TextFile.txt"; //$NON-NLS-1$
|
||||
File file = ResourceUtil.getFileFromResource(this.getClass(), filename);
|
||||
Assert.assertNotNull(file);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,445 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.talend.commons.utils.threading.Locker;
|
||||
import org.talend.commons.utils.threading.Locker.LockerValue;
|
||||
import org.talend.commons.utils.threading.locker.operators.AbstractLockerOperator;
|
||||
import org.talend.commons.utils.threading.locker.operators.LockOperator;
|
||||
import org.talend.commons.utils.threading.locker.operators.ResultContainer;
|
||||
import org.talend.commons.utils.threading.locker.operators.UnlockOperator;
|
||||
import org.talend.commons.utils.threading.locker.operators.WaitForLockThenUnlockOperator;
|
||||
import org.talend.commons.utils.threading.threadsafetester.AbstractThreadSafetyTester;
|
||||
|
||||
public class LockerTest {
|
||||
|
||||
private static final int WAIT_THREAD_STARTED = 100;
|
||||
|
||||
private static final int WAIT_JOIN = 100;
|
||||
|
||||
class WaitForLockThread extends Thread {
|
||||
|
||||
private Locker locker;
|
||||
|
||||
Integer key;
|
||||
|
||||
public Throwable throwable;
|
||||
|
||||
public WaitForLockThread(Locker locker, Integer key) {
|
||||
super();
|
||||
this.locker = locker;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
locker.waitForLock(key);
|
||||
} catch (Throwable e) {
|
||||
throwable = e;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class WaitForLockTwiceThread extends Thread {
|
||||
|
||||
private Locker locker;
|
||||
|
||||
Integer key;
|
||||
|
||||
public Throwable throwable;
|
||||
|
||||
public WaitForLockTwiceThread(Locker locker, Integer key) {
|
||||
super();
|
||||
this.locker = locker;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
locker.waitForLock(key);
|
||||
locker.waitForLock(key);
|
||||
} catch (Throwable e) {
|
||||
throwable = e;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class UnlockThread extends Thread {
|
||||
|
||||
private Locker locker;
|
||||
|
||||
Integer key;
|
||||
|
||||
public Throwable throwable;
|
||||
|
||||
public UnlockThread(Locker locker, Integer key) {
|
||||
super();
|
||||
this.locker = locker;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
locker.unlock(key);
|
||||
} catch (Throwable e) {
|
||||
throwable = e;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testIsLocked() throws Throwable {
|
||||
final Locker locker = new Locker();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertFalse(isLocked);
|
||||
|
||||
boolean previouslyLocked = locker.lock(keyOne);
|
||||
assertFalse(previouslyLocked);
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertTrue(isLocked);
|
||||
|
||||
boolean hasUnlocked = locker.unlock(keyOne);
|
||||
assertTrue(hasUnlocked);
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertFalse(isLocked);
|
||||
}
|
||||
|
||||
@Test(expected = InterruptedException.class, timeout = 2000)
|
||||
// @Test(expected = InterruptedException.class)
|
||||
public void testWaitForLock_LockTwiceWithSameKey() throws Throwable {
|
||||
final Locker locker = new Locker();
|
||||
|
||||
final int keyOne = 1;
|
||||
WaitForLockThread threadWaitForLockKeyOne_first = new WaitForLockThread(locker, keyOne);
|
||||
threadWaitForLockKeyOne_first.start();
|
||||
threadWaitForLockKeyOne_first.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLockKeyOne_first.isAlive());
|
||||
assertNull(threadWaitForLockKeyOne_first.throwable);
|
||||
|
||||
WaitForLockThread threadWaitForLockKeyOne_second = new WaitForLockThread(locker, keyOne);
|
||||
threadWaitForLockKeyOne_second.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertTrue(threadWaitForLockKeyOne_second.isAlive());
|
||||
threadWaitForLockKeyOne_second.interrupt();
|
||||
threadWaitForLockKeyOne_second.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLockKeyOne_second.isAlive());
|
||||
assertNotNull(threadWaitForLockKeyOne_second.throwable);
|
||||
throw threadWaitForLockKeyOne_second.throwable;
|
||||
}
|
||||
|
||||
@Test(expected = InterruptedException.class, timeout = 2000)
|
||||
// @Test(expected = InterruptedException.class)
|
||||
public void testWaitForLock_LockTwiceWithSamePrimitiveValueButDifferentInteger() throws Throwable {
|
||||
final Locker locker = new Locker();
|
||||
|
||||
final int keyOne = 1;
|
||||
final Integer keyOneInteger1 = new Integer(keyOne);
|
||||
WaitForLockThread threadWaitForLockKeyOne_first = new WaitForLockThread(locker, keyOneInteger1);
|
||||
threadWaitForLockKeyOne_first.start();
|
||||
threadWaitForLockKeyOne_first.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLockKeyOne_first.isAlive());
|
||||
assertNull(threadWaitForLockKeyOne_first.throwable);
|
||||
|
||||
final Integer keyOneInteger2 = new Integer(keyOne);
|
||||
WaitForLockThread threadWaitForLockKeyOne_second = new WaitForLockThread(locker, keyOneInteger2);
|
||||
threadWaitForLockKeyOne_second.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertTrue(threadWaitForLockKeyOne_second.isAlive());
|
||||
threadWaitForLockKeyOne_second.interrupt();
|
||||
threadWaitForLockKeyOne_second.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLockKeyOne_second.isAlive());
|
||||
assertNotNull(threadWaitForLockKeyOne_second.throwable);
|
||||
throw threadWaitForLockKeyOne_second.throwable;
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
public void testWaitForLock_LockTwiceWithDifferentKeys() throws Throwable {
|
||||
final Locker locker = new Locker();
|
||||
|
||||
final int keyOne = 1;
|
||||
WaitForLockThread threadWaitForLockKeyOne_first = new WaitForLockThread(locker, keyOne);
|
||||
threadWaitForLockKeyOne_first.start();
|
||||
threadWaitForLockKeyOne_first.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLockKeyOne_first.isAlive());
|
||||
assertNull(threadWaitForLockKeyOne_first.throwable);
|
||||
|
||||
final int keyTwo = 2;
|
||||
WaitForLockThread threadLockKeyOne_second = new WaitForLockThread(locker, keyTwo);
|
||||
threadLockKeyOne_second.start();
|
||||
threadLockKeyOne_second.join(WAIT_JOIN);
|
||||
assertFalse(threadLockKeyOne_second.isAlive());
|
||||
assertNull(threadWaitForLockKeyOne_first.throwable);
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test
|
||||
public void testWaitForLockThenUnlock() throws Throwable {
|
||||
final Locker locker = new Locker();
|
||||
|
||||
final int keyOne = 1;
|
||||
WaitForLockThread threadWaitForLockKeyOne = new WaitForLockThread(locker, keyOne);
|
||||
threadWaitForLockKeyOne.start();
|
||||
threadWaitForLockKeyOne.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLockKeyOne.isAlive());
|
||||
assertNull(threadWaitForLockKeyOne.throwable);
|
||||
|
||||
UnlockThread threadUnlockKeyOne = new UnlockThread(locker, keyOne);
|
||||
threadUnlockKeyOne.start();
|
||||
threadUnlockKeyOne.join(WAIT_JOIN);
|
||||
assertFalse(threadUnlockKeyOne.isAlive());
|
||||
assertNull(threadUnlockKeyOne.throwable);
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test
|
||||
public void testWaitForLock_waitForLockTwiceFromFirstLockerThread() throws Throwable {
|
||||
boolean allowReentrantLockFromLockerThread = true;
|
||||
final Locker locker = new Locker(allowReentrantLockFromLockerThread);
|
||||
|
||||
final int keyOne = 1;
|
||||
WaitForLockTwiceThread threadWaitForLockTwiceKeyOne = new WaitForLockTwiceThread(locker, keyOne);
|
||||
threadWaitForLockTwiceKeyOne.start();
|
||||
threadWaitForLockTwiceKeyOne.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLockTwiceKeyOne.isAlive());
|
||||
assertNull(threadWaitForLockTwiceKeyOne.throwable);
|
||||
}
|
||||
|
||||
@Test(expected = InterruptedException.class, timeout = 2000)
|
||||
// @Test(expected = InterruptedException.class)
|
||||
public void testWaitForLock_waitForLockTwiceFromDifferentThread() throws Throwable {
|
||||
boolean allowReentrantLockFromLockerThread = true;
|
||||
final Locker locker = new Locker(allowReentrantLockFromLockerThread);
|
||||
|
||||
final int keyOne = 1;
|
||||
WaitForLockThread threadWaitForLock_threadOne = new WaitForLockThread(locker, keyOne);
|
||||
threadWaitForLock_threadOne.start();
|
||||
threadWaitForLock_threadOne.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLock_threadOne.isAlive());
|
||||
assertNull(threadWaitForLock_threadOne.throwable);
|
||||
|
||||
WaitForLockThread threadWaitForLock_threadTwo = new WaitForLockThread(locker, keyOne);
|
||||
threadWaitForLock_threadTwo.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
threadWaitForLock_threadTwo.interrupt();
|
||||
assertTrue(threadWaitForLock_threadTwo.isAlive());
|
||||
threadWaitForLock_threadTwo.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLock_threadTwo.isAlive());
|
||||
assertNotNull(threadWaitForLock_threadTwo.throwable);
|
||||
throw threadWaitForLock_threadTwo.throwable;
|
||||
}
|
||||
|
||||
@Test(expected = InterruptedException.class, timeout = 2000)
|
||||
// @Test(expected = InterruptedException.class)
|
||||
public void testWaitForLock_waitForLockTwiceFromSameThread_forbidReentrantLockFromOtherThread() throws Throwable {
|
||||
boolean allowReentrantLockFromLockerThread = false;
|
||||
final Locker locker = new Locker(allowReentrantLockFromLockerThread);
|
||||
|
||||
final int keyOne = 1;
|
||||
WaitForLockTwiceThread threadWaitForLockTwiceKeyOne = new WaitForLockTwiceThread(locker, keyOne);
|
||||
threadWaitForLockTwiceKeyOne.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertTrue(threadWaitForLockTwiceKeyOne.isAlive());
|
||||
threadWaitForLockTwiceKeyOne.interrupt();
|
||||
threadWaitForLockTwiceKeyOne.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLockTwiceKeyOne.isAlive());
|
||||
assertNotNull(threadWaitForLockTwiceKeyOne.throwable);
|
||||
throw threadWaitForLockTwiceKeyOne.throwable;
|
||||
}
|
||||
|
||||
@Test(expected = InterruptedException.class, timeout = 2000)
|
||||
// @Test(expected = InterruptedException.class)
|
||||
public void testWaitForLock_waitForLockTwiceFromDifferentThread_forbidReentrantLockFromLockerThread() throws Throwable {
|
||||
boolean allowReentrantLockFromLockerThread = false;
|
||||
final Locker locker = new Locker(allowReentrantLockFromLockerThread);
|
||||
|
||||
final int keyOne = 1;
|
||||
WaitForLockThread threadWaitForLock_threadOne = new WaitForLockThread(locker, keyOne);
|
||||
threadWaitForLock_threadOne.start();
|
||||
threadWaitForLock_threadOne.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLock_threadOne.isAlive());
|
||||
assertNull(threadWaitForLock_threadOne.throwable);
|
||||
|
||||
WaitForLockThread threadWaitForLock_threadTwo = new WaitForLockThread(locker, keyOne);
|
||||
threadWaitForLock_threadTwo.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertTrue(threadWaitForLock_threadTwo.isAlive());
|
||||
threadWaitForLock_threadTwo.interrupt();
|
||||
threadWaitForLock_threadTwo.join(WAIT_JOIN);
|
||||
assertFalse(threadWaitForLock_threadTwo.isAlive());
|
||||
assertNotNull(threadWaitForLock_threadTwo.throwable);
|
||||
throw threadWaitForLock_threadTwo.throwable;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreadSafetyWithLockUnlock() throws Exception {
|
||||
|
||||
final Locker locker = new Locker();
|
||||
int nOperatorsByClassOperator = 10;
|
||||
final int nOperationsByOperator = 10000;
|
||||
|
||||
final ResultContainer resultContainer = new ResultContainer();
|
||||
|
||||
class LockerThreadSafetyTester extends AbstractThreadSafetyTester<AbstractLockerOperator> {
|
||||
|
||||
public LockerThreadSafetyTester(int nOperatorsByClassOperator,
|
||||
Class<? extends AbstractLockerOperator>... classOperators) {
|
||||
super(nOperatorsByClassOperator, classOperators);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.talend.commons.utils.threading.AbstractThreadSafetyTester#initInstance(org.talend.commons.utils.threading
|
||||
* .IThreadSafetyOperator)
|
||||
*/
|
||||
protected void initInstance(AbstractLockerOperator operatorInstance) {
|
||||
operatorInstance.setLocker(locker);
|
||||
operatorInstance.setnOperationsByOperator(nOperationsByOperator);
|
||||
operatorInstance.setResultContainer(resultContainer);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.talend.commons.utils.threading.AbstractThreadSafetyTester#assertFinal()
|
||||
*/
|
||||
@Override
|
||||
protected void assertFinal() {
|
||||
int expectedSumLockedAtEnd = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
LockerValue lockerValue = locker.getLocker(i);
|
||||
if (lockerValue != null) {
|
||||
expectedSumLockedAtEnd++;
|
||||
}
|
||||
}
|
||||
int actualSumLockedAtEnd = resultContainer.sumLocked.get() - resultContainer.sumUnlocked.get();
|
||||
assertThat(actualSumLockedAtEnd, is(expectedSumLockedAtEnd));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
LockerThreadSafetyTester lockerThreadSafetyTester = new LockerThreadSafetyTester(nOperatorsByClassOperator,
|
||||
LockOperator.class, UnlockOperator.class);
|
||||
lockerThreadSafetyTester.start();
|
||||
|
||||
}
|
||||
|
||||
@Test(timeout = 10000)
|
||||
public void testThreadSafetyWithWaitForLockThenUnlock_allowReentrantLockFromOtherThread() throws Exception {
|
||||
boolean allowReentrantLockFromOtherThread = true;
|
||||
final Locker locker = new Locker(allowReentrantLockFromOtherThread);
|
||||
final int nOperatorsByClassOperator = 30;
|
||||
final int nOperationsByOperator = 500;
|
||||
launchThreadSafetyTestWithWaitForLockThenUnlock(locker, nOperatorsByClassOperator, nOperationsByOperator);
|
||||
}
|
||||
|
||||
@Test(timeout = 10000)
|
||||
public void testThreadSafetyWithWaitForLockThenUnlock_forbidReentrantLockFromOtherThread() throws Exception {
|
||||
boolean allowReentrantLockFromOtherThread = false;
|
||||
final Locker locker = new Locker(allowReentrantLockFromOtherThread);
|
||||
final int nOperatorsByClassOperator = 30;
|
||||
final int nOperationsByOperator = 500;
|
||||
launchThreadSafetyTestWithWaitForLockThenUnlock(locker, nOperatorsByClassOperator, nOperationsByOperator);
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
// @Test
|
||||
public void testThreadSafetyWithWaitForLockThenUnlock_minimalOperations() throws Exception {
|
||||
boolean allowReentrantLockFromOtherThread = true;
|
||||
final Locker locker = new Locker(allowReentrantLockFromOtherThread);
|
||||
final int nOperatorsByClassOperator = 2;
|
||||
final int nOperationsByOperator = 1;
|
||||
launchThreadSafetyTestWithWaitForLockThenUnlock(locker, nOperatorsByClassOperator, nOperationsByOperator);
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
// @Test
|
||||
public void testThreadSafetyWithWaitForLockThenUnlock() throws Exception {
|
||||
boolean allowReentrantLockFromOtherThread = true;
|
||||
final Locker locker = new Locker(allowReentrantLockFromOtherThread);
|
||||
final int nOperatorsByClassOperator = 200;
|
||||
final int nOperationsByOperator = 1;
|
||||
launchThreadSafetyTestWithWaitForLockThenUnlock(locker, nOperatorsByClassOperator, nOperationsByOperator);
|
||||
}
|
||||
|
||||
private void launchThreadSafetyTestWithWaitForLockThenUnlock(final Locker locker, final int nOperatorsByClassOperator,
|
||||
final int nOperationsByOperator) throws Exception {
|
||||
final ResultContainer resultContainer = new ResultContainer();
|
||||
|
||||
class LockerThreadSafetyTester extends AbstractThreadSafetyTester<AbstractLockerOperator> {
|
||||
|
||||
public LockerThreadSafetyTester(int nOperatorsByClassOperator,
|
||||
Class<? extends AbstractLockerOperator>... classOperators) {
|
||||
super(nOperatorsByClassOperator, classOperators);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.talend.commons.utils.threading.AbstractThreadSafetyTester#initInstance(org.talend.commons.utils.threading
|
||||
* .IThreadSafetyOperator)
|
||||
*/
|
||||
protected void initInstance(AbstractLockerOperator operatorInstance) {
|
||||
operatorInstance.setLocker(locker);
|
||||
operatorInstance.setnOperationsByOperator(nOperationsByOperator);
|
||||
operatorInstance.setResultContainer(resultContainer);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.talend.commons.utils.threading.AbstractThreadSafetyTester#assertFinal()
|
||||
*/
|
||||
@Override
|
||||
protected void assertFinal() {
|
||||
int actualSumLockedAtEnd = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
LockerValue lockerValue = locker.getLocker(i);
|
||||
if (lockerValue != null) {
|
||||
actualSumLockedAtEnd++;
|
||||
}
|
||||
}
|
||||
assertThat(actualSumLockedAtEnd, is(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
LockerThreadSafetyTester lockerThreadSafetyTester = new LockerThreadSafetyTester(nOperatorsByClassOperator,
|
||||
WaitForLockThenUnlockOperator.class);
|
||||
lockerThreadSafetyTester.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.locker.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.Locker;
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
|
||||
public abstract class AbstractLockerOperator implements IThreadSafetyOperator {
|
||||
|
||||
protected Locker locker;
|
||||
|
||||
protected int nOperationsByOperator;
|
||||
|
||||
protected ResultContainer resultContainer;
|
||||
|
||||
/**
|
||||
* Sets the locker.
|
||||
*
|
||||
* @param locker the locker to set
|
||||
*/
|
||||
public void setLocker(Locker locker) {
|
||||
this.locker = locker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nOperationsByOperator.
|
||||
*
|
||||
* @param nOperationsByOperator the nOperationsByOperator to set
|
||||
*/
|
||||
public void setnOperationsByOperator(int nOperationsByOperator) {
|
||||
this.nOperationsByOperator = nOperationsByOperator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resultContainer.
|
||||
*
|
||||
* @param resultContainer the resultContainer to set
|
||||
*/
|
||||
public void setResultContainer(ResultContainer resultContainer) {
|
||||
this.resultContainer = resultContainer;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package org.talend.commons.utils.threading.locker.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
|
||||
public class LockOperator extends AbstractLockerOperator implements IThreadSafetyOperator {
|
||||
|
||||
public void doOperations() {
|
||||
int sumLocked = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
boolean alreadyLocked = locker.lock(i);
|
||||
boolean newLock = !alreadyLocked;
|
||||
if (newLock) {
|
||||
sumLocked++;
|
||||
}
|
||||
}
|
||||
resultContainer.sumLocked.getAndAdd(sumLocked);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.locker.operators;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ResultContainer {
|
||||
|
||||
public final AtomicInteger sumLocked = new AtomicInteger(0);
|
||||
|
||||
public final AtomicInteger sumUnlocked = new AtomicInteger(0);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package org.talend.commons.utils.threading.locker.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class UnlockInvertOperator extends AbstractLockerOperator implements IThreadSafetyOperator {
|
||||
|
||||
public void doOperations() throws InterruptedException {
|
||||
Thread.sleep(1000);
|
||||
int sumUnlocked = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
boolean hasUnlocked = locker.unlock(i);
|
||||
if (hasUnlocked) {
|
||||
sumUnlocked++;
|
||||
}
|
||||
}
|
||||
resultContainer.sumLocked.getAndAdd(sumUnlocked);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.talend.commons.utils.threading.locker.operators;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class UnlockOperator extends AbstractLockerOperator implements IThreadSafetyOperator {
|
||||
|
||||
public void doOperations() {
|
||||
int sumUnlocked = 0;
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
boolean hasUnlocked = locker.unlock(i);
|
||||
if (hasUnlocked) {
|
||||
sumUnlocked++;
|
||||
}
|
||||
}
|
||||
resultContainer.sumUnlocked.getAndAdd(sumUnlocked);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.talend.commons.utils.threading.locker.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class WaitForLockOperator extends AbstractLockerOperator implements IThreadSafetyOperator {
|
||||
|
||||
public void doOperations() throws InterruptedException {
|
||||
int sumLocked = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
locker.waitForLock(i);
|
||||
sumLocked++;
|
||||
}
|
||||
resultContainer.sumLocked.getAndAdd(sumLocked);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.talend.commons.utils.threading.locker.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class WaitForLockThenUnlockOperator extends AbstractLockerOperator implements IThreadSafetyOperator {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doOperations() throws InterruptedException {
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
try {
|
||||
locker.waitForLock(i);
|
||||
System.out.println("Locked " + i);
|
||||
Thread.sleep(10);
|
||||
} finally {
|
||||
System.out.println("Unlocking " + i);
|
||||
locker.unlock(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,813 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.lockerbykey;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.MethodRule;
|
||||
import org.junit.rules.Timeout;
|
||||
import org.talend.commons.utils.memory.MemoryMeasurer;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.AbstractLockerByKeyOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.CleanOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.LockThenUnlockOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.ResultContainer;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.TryLockThenUnlockOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.TryLockWithTimeoutThenUnlockOperator;
|
||||
import org.talend.commons.utils.threading.threadsafetester.AbstractThreadSafetyTester;
|
||||
|
||||
public class LockerByKeyTest {
|
||||
|
||||
@Rule
|
||||
public MethodRule globalTimeout = new Timeout(60000);
|
||||
|
||||
private static final int WAIT_THREAD_STARTED = 200;
|
||||
|
||||
private static final int WAIT_JOIN = 200;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
protected ILockerByKey createLockerInstance() {
|
||||
// default implementation when running this TestCase
|
||||
return new LockerByKey();
|
||||
}
|
||||
|
||||
class LockInterruptiblyThread extends Thread {
|
||||
|
||||
private ILockerByKey locker;
|
||||
|
||||
Integer key;
|
||||
|
||||
public Throwable throwable;
|
||||
|
||||
public LockInterruptiblyThread(ILockerByKey locker, Integer key) {
|
||||
super();
|
||||
this.locker = locker;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
locker.lockInterruptibly(key);
|
||||
} catch (Throwable e) {
|
||||
throwable = e;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class LockInterruptiblyTwiceThread extends Thread {
|
||||
|
||||
private ILockerByKey locker;
|
||||
|
||||
Integer key;
|
||||
|
||||
public Throwable throwable;
|
||||
|
||||
public LockInterruptiblyTwiceThread(ILockerByKey locker, Integer key) {
|
||||
super();
|
||||
this.locker = locker;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
locker.lockInterruptibly(key);
|
||||
locker.lockInterruptibly(key);
|
||||
} catch (Throwable e) {
|
||||
throwable = e;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class UnlockThread extends Thread {
|
||||
|
||||
private ILockerByKey locker;
|
||||
|
||||
Integer key;
|
||||
|
||||
public Throwable throwable;
|
||||
|
||||
public UnlockThread(ILockerByKey locker, Integer key) {
|
||||
super();
|
||||
this.locker = locker;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
locker.unlock(key);
|
||||
} catch (Throwable e) {
|
||||
throwable = e;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testIsLocked_with_Lock_then_Unlock() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
locker.lockInterruptibly(keyOne);
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
boolean hasUnlocked = locker.unlock(keyOne);
|
||||
assertThat(hasUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
// @Test(timeout = 2000)
|
||||
@Test()
|
||||
public void testLockWithThread1_and_UnlockWithThread2() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
locker.lockInterruptibly(keyOne);
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
ExecutorService poolRunnableUnlock = Executors.newCachedThreadPool();
|
||||
|
||||
// UNLOCK STEP
|
||||
Callable<Boolean> runnableUnlock = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
return locker.unlock(keyOne);
|
||||
}
|
||||
};
|
||||
Future<Boolean> futureUnlock = poolRunnableUnlock.submit(runnableUnlock);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
try {
|
||||
futureUnlock.get(2, TimeUnit.SECONDS);
|
||||
fail("expected = IllegalMonitorStateException.class");
|
||||
} catch (Exception e) {
|
||||
if (!(e.getCause() instanceof IllegalMonitorStateException)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testTryLockWithThread1_and_UnlockWithThread2() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
boolean locked = locker.tryLock(keyOne);
|
||||
assertThat(locked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
ExecutorService poolRunnable2 = Executors.newCachedThreadPool();
|
||||
|
||||
// UNLOCK STEP
|
||||
Callable<Boolean> runnableUnlock = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
return locker.unlock(keyOne);
|
||||
}
|
||||
};
|
||||
Future<Boolean> futureUnlock = poolRunnable2.submit(runnableUnlock);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
try {
|
||||
futureUnlock.get(2, TimeUnit.SECONDS);
|
||||
fail("expected = IllegalMonitorStateException.class");
|
||||
} catch (Exception e) {
|
||||
if (!(e.getCause() instanceof IllegalMonitorStateException)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnlock_with_noPreviousLock() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
boolean unlocked = locker.unlock(keyOne);
|
||||
assertThat(unlocked, is(false));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testCleanEnabledDefault() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
locker.lockInterruptibly(i);
|
||||
|
||||
isLocked = locker.isLocked(i);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
boolean hasUnlocked = locker.unlock(i);
|
||||
assertThat(hasUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(i);
|
||||
assertThat(isLocked, is(false));
|
||||
}
|
||||
|
||||
/*
|
||||
* Be warn, the last is not removed by the auto clean, need to call clean again to clear all.
|
||||
*/
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
assertThat(locker.getLockerValue(i), is(nullValue()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testCleanEnabledProvidedPeriod() throws Throwable {
|
||||
final ILockerByKey<Integer> locker = new LockerByKey<Integer>(true, 600);
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
locker.lockInterruptibly(i);
|
||||
|
||||
isLocked = locker.isLocked(i);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
boolean hasUnlocked = locker.unlock(i);
|
||||
assertThat(hasUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(i);
|
||||
assertThat(isLocked, is(false));
|
||||
}
|
||||
|
||||
/*
|
||||
* Be warn, the last is not removed by the auto clean, need to call clean again to clear all.
|
||||
*/
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (i < 600) {
|
||||
assertThat(locker.getLockerValue(i), is(nullValue()));
|
||||
} else {
|
||||
assertThat(locker.getLockerValue(i), is(notNullValue()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testShutdown_Lock() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
ExecutorService poolRunnable1 = Executors.newCachedThreadPool();
|
||||
ExecutorService poolRunnable2 = Executors.newCachedThreadPool();
|
||||
|
||||
final int keyOne = 1;
|
||||
final String expectedResult = "ended";
|
||||
Callable<String> runnable = new Callable<String>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
locker.lockInterruptibly(keyOne);
|
||||
return expectedResult;
|
||||
}
|
||||
};
|
||||
|
||||
Future<String> future1 = poolRunnable1.submit(runnable);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
String result1 = future1.get(2, TimeUnit.SECONDS);
|
||||
assertThat(result1, is(expectedResult));
|
||||
|
||||
Future<String> future2 = poolRunnable2.submit(runnable);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
locker.shutdown();
|
||||
|
||||
try {
|
||||
future2.get(2, TimeUnit.SECONDS);
|
||||
fail("Should be interrupted by the shutdown");
|
||||
} catch (Exception e) {
|
||||
boolean isInterruptedException = e.getCause() instanceof InterruptedException;
|
||||
if (!isInterruptedException) {
|
||||
e.printStackTrace();
|
||||
fail("Should be an InterruptedException, please read logs");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testShutdown_TryLockWithTimeout() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
ExecutorService poolRunnable1 = Executors.newCachedThreadPool();
|
||||
ExecutorService poolRunnable2 = Executors.newCachedThreadPool();
|
||||
|
||||
final int keyOne = 1;
|
||||
final String expectedResult = "ended";
|
||||
Callable<String> runnable = new Callable<String>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
locker.tryLock(keyOne, 10000);
|
||||
return expectedResult;
|
||||
}
|
||||
};
|
||||
|
||||
Future<String> future1 = poolRunnable1.submit(runnable);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
String result1 = future1.get(2, TimeUnit.SECONDS);
|
||||
assertThat(result1, is(expectedResult));
|
||||
|
||||
Future<String> future2 = poolRunnable2.submit(runnable);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
locker.shutdown();
|
||||
|
||||
try {
|
||||
future2.get(2, TimeUnit.SECONDS);
|
||||
fail("Should be interrupted by the shutdown");
|
||||
} catch (Exception e) {
|
||||
boolean isInterruptedException = e.getCause() instanceof InterruptedException;
|
||||
if (!isInterruptedException) {
|
||||
e.printStackTrace();
|
||||
fail("Should be an InterruptedException, please read logs");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnlock_withGetLockerValue() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
LockerValue lockerValue = locker.getLockerValue(keyOne);
|
||||
assertThat(lockerValue, is(nullValue()));
|
||||
|
||||
locker.lockInterruptibly(keyOne);
|
||||
|
||||
LockerValue lockerValue1 = locker.getLockerValue(keyOne);
|
||||
assertThat(lockerValue1, is(notNullValue()));
|
||||
|
||||
boolean hasUnlocked = locker.unlock(keyOne);
|
||||
assertThat(hasUnlocked, is(true));
|
||||
|
||||
LockerValue lockerValue2 = locker.getLockerValue(keyOne);
|
||||
assertThat(lockerValue2, is(lockerValue1));
|
||||
|
||||
locker.shutdown();
|
||||
LockerValue lockerValue3 = locker.getLockerValue(keyOne);
|
||||
assertThat(lockerValue3, is(nullValue()));
|
||||
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testLock_LockTwiceWithSameKey() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyThread threadLockKeyOne_first = new LockInterruptiblyThread(locker, keyOne);
|
||||
threadLockKeyOne_first.start();
|
||||
threadLockKeyOne_first.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_first.isAlive(), is(false));
|
||||
if (threadLockKeyOne_first.throwable != null) {
|
||||
throw threadLockKeyOne_first.throwable;
|
||||
}
|
||||
|
||||
LockInterruptiblyThread threadLockKeyOne_second = new LockInterruptiblyThread(locker, keyOne);
|
||||
threadLockKeyOne_second.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(true));
|
||||
threadLockKeyOne_second.interrupt();
|
||||
threadLockKeyOne_second.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(false));
|
||||
assertThat(threadLockKeyOne_second.throwable, is(notNullValue()));
|
||||
assertThat(threadLockKeyOne_second.throwable, is(instanceOf(InterruptedException.class)));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testLock_LockTwiceWithSamePrimitiveValueButDifferentInteger() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
final Integer keyOneInteger1 = new Integer(keyOne);
|
||||
LockInterruptiblyThread threadLockKeyOne_first = new LockInterruptiblyThread(locker, keyOneInteger1);
|
||||
threadLockKeyOne_first.start();
|
||||
threadLockKeyOne_first.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_first.isAlive(), is(false));
|
||||
if (threadLockKeyOne_first.throwable != null) {
|
||||
throw threadLockKeyOne_first.throwable;
|
||||
}
|
||||
|
||||
final Integer keyOneInteger2 = new Integer(keyOne);
|
||||
LockInterruptiblyThread threadLockKeyOne_second = new LockInterruptiblyThread(locker, keyOneInteger2);
|
||||
threadLockKeyOne_second.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(true));
|
||||
threadLockKeyOne_second.interrupt();
|
||||
threadLockKeyOne_second.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(false));
|
||||
assertThat(threadLockKeyOne_second.throwable, is(notNullValue()));
|
||||
assertThat(threadLockKeyOne_second.throwable, is(instanceOf(InterruptedException.class)));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
public void testLock_LockTwiceWithDifferentKeys() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyThread threadLockKeyOne_first = new LockInterruptiblyThread(locker, keyOne);
|
||||
threadLockKeyOne_first.start();
|
||||
threadLockKeyOne_first.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_first.isAlive(), is(false));
|
||||
if (threadLockKeyOne_first.throwable != null) {
|
||||
throw threadLockKeyOne_first.throwable;
|
||||
}
|
||||
|
||||
final int keyTwo = 2;
|
||||
LockInterruptiblyThread threadLockKeyOne_second = new LockInterruptiblyThread(locker, keyTwo);
|
||||
threadLockKeyOne_second.start();
|
||||
threadLockKeyOne_second.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(false));
|
||||
if (threadLockKeyOne_first.throwable != null) {
|
||||
throw threadLockKeyOne_first.throwable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test
|
||||
public void testLock_ThenUnlockFromOtherThread() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyThread threadLockKeyOne = new LockInterruptiblyThread(locker, keyOne);
|
||||
threadLockKeyOne.start();
|
||||
threadLockKeyOne.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne.isAlive(), is(false));
|
||||
if (threadLockKeyOne.throwable != null) {
|
||||
throw threadLockKeyOne.throwable;
|
||||
}
|
||||
|
||||
UnlockThread threadUnlockKeyOne = new UnlockThread(locker, keyOne);
|
||||
threadUnlockKeyOne.start();
|
||||
threadUnlockKeyOne.join(WAIT_JOIN);
|
||||
assertThat(threadUnlockKeyOne.isAlive(), is(false));
|
||||
assertThat(threadUnlockKeyOne.throwable, is(instanceOf(IllegalMonitorStateException.class)));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testLock_LockTwiceFromDifferentThread() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyThread threadLock_threadOne = new LockInterruptiblyThread(locker, keyOne);
|
||||
threadLock_threadOne.start();
|
||||
threadLock_threadOne.join(WAIT_JOIN);
|
||||
assertThat(threadLock_threadOne.isAlive(), is(false));
|
||||
if (threadLock_threadOne.throwable != null) {
|
||||
throw threadLock_threadOne.throwable;
|
||||
}
|
||||
|
||||
LockInterruptiblyThread threadLock_threadTwo = new LockInterruptiblyThread(locker, keyOne);
|
||||
threadLock_threadTwo.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
threadLock_threadTwo.interrupt();
|
||||
assertThat(threadLock_threadTwo.isAlive(), is(true));
|
||||
threadLock_threadTwo.join(WAIT_JOIN);
|
||||
assertThat(threadLock_threadTwo.isAlive(), is(false));
|
||||
assertThat(threadLock_threadTwo.throwable, is(notNullValue()));
|
||||
assertThat(threadLock_threadTwo.throwable, is(instanceOf(InterruptedException.class)));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testLock_LockTwiceFromSameThread_forbidReentrantLockFromOtherThread() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyTwiceThread threadLockTwiceKeyOne = new LockInterruptiblyTwiceThread(locker, keyOne);
|
||||
threadLockTwiceKeyOne.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertThat(threadLockTwiceKeyOne.isAlive(), is(false));
|
||||
assertThat(threadLockTwiceKeyOne.throwable, is(nullValue()));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testLock_LockTwiceFromDifferentThread_forbidReentrantLockFromLockerThread() throws Throwable {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyThread threadLock_threadOne = new LockInterruptiblyThread(locker, keyOne);
|
||||
threadLock_threadOne.start();
|
||||
threadLock_threadOne.join(WAIT_JOIN);
|
||||
assertThat(threadLock_threadOne.isAlive(), is(false));
|
||||
if (threadLock_threadOne.throwable != null) {
|
||||
throw threadLock_threadOne.throwable;
|
||||
}
|
||||
|
||||
LockInterruptiblyThread threadLock_threadTwo = new LockInterruptiblyThread(locker, keyOne);
|
||||
threadLock_threadTwo.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertThat(threadLock_threadTwo.isAlive(), is(true));
|
||||
threadLock_threadTwo.interrupt();
|
||||
threadLock_threadTwo.join(WAIT_JOIN);
|
||||
assertThat(threadLock_threadTwo.isAlive(), is(false));
|
||||
assertThat(threadLock_threadTwo.throwable, is(notNullValue()));
|
||||
assertThat(threadLock_threadTwo.throwable, is(instanceOf(InterruptedException.class)));
|
||||
}
|
||||
|
||||
@Test(timeout = 1000)
|
||||
// @Test
|
||||
public void testGetSuspectLocks() throws Exception {
|
||||
final ILockerByKey<Integer> locker = createLockerInstance();
|
||||
locker.setDetectSuspectLocks(true);
|
||||
int keyOne = 1;
|
||||
|
||||
locker.lockInterruptibly(keyOne);
|
||||
List<LockerValue<Integer>> suspectLocks = locker.getSuspectLocks(1000);
|
||||
assertThat(suspectLocks.size(), is(0));
|
||||
|
||||
Thread.sleep(100);
|
||||
suspectLocks = locker.getSuspectLocks(50);
|
||||
assertThat(suspectLocks.size(), is(1));
|
||||
|
||||
locker.unlock(keyOne);
|
||||
suspectLocks = locker.getSuspectLocks(50);
|
||||
assertThat(suspectLocks.size(), is(0));
|
||||
}
|
||||
|
||||
@Test(timeout = 20000)
|
||||
// @Test
|
||||
public void testThreadSafety_LockThenUnlock() throws Exception {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
final int nOperatorsByClassOperator = 30;
|
||||
final int nOperationsByOperator = 500;
|
||||
boolean assertEntriesLessThanCleanPeriod = true;
|
||||
boolean warmupRound = false;
|
||||
boolean shutdownAtEnd = true;
|
||||
launchThreadSafetyTest(locker, nOperatorsByClassOperator, nOperationsByOperator, assertEntriesLessThanCleanPeriod,
|
||||
warmupRound, shutdownAtEnd, LockThenUnlockOperator.class, TryLockWithTimeoutThenUnlockOperator.class,
|
||||
TryLockThenUnlockOperator.class);
|
||||
}
|
||||
|
||||
@Test(timeout = 20000)
|
||||
// @Test
|
||||
public void testThreadSafety_LockThenUnlock_with_randomClean() throws Exception {
|
||||
final ILockerByKey locker = createLockerInstance();
|
||||
final int nOperatorsByClassOperator = 30;
|
||||
final int nOperationsByOperator = 500;
|
||||
boolean assertEntriesLessThanCleanPeriod = true;
|
||||
boolean warmupRound = false;
|
||||
boolean shutdownAtEnd = true;
|
||||
launchThreadSafetyTest(locker, nOperatorsByClassOperator, nOperationsByOperator, assertEntriesLessThanCleanPeriod,
|
||||
warmupRound, shutdownAtEnd, LockThenUnlockOperator.class, TryLockWithTimeoutThenUnlockOperator.class,
|
||||
TryLockThenUnlockOperator.class, CleanOperator.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to show the increasing memory with old Locker and stable memory with new LockerByKey
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test(timeout = 30000)
|
||||
// @Test
|
||||
public void testMemory_iterations() throws Exception {
|
||||
ILockerByKey locker = new LockerByKeyUnrestricted();
|
||||
final int nOperatorsByClassOperator = 30;
|
||||
final int nOperationsByOperator = 50;
|
||||
boolean assertEntriesLessThanCleanPeriod = true;
|
||||
boolean warmupRound = true;
|
||||
boolean shutdownAtEnd = false;
|
||||
int warmupRounds = 3;
|
||||
int mesureRounds = 3;
|
||||
|
||||
MemoryMeasurer globalMemoryMeasurer = new MemoryMeasurer();
|
||||
globalMemoryMeasurer.begin();
|
||||
for (int i = 0; i < warmupRounds; i++) {
|
||||
launchThreadSafetyTest(locker, nOperatorsByClassOperator, nOperationsByOperator, assertEntriesLessThanCleanPeriod,
|
||||
warmupRound, shutdownAtEnd, LockThenUnlockOperator.class, TryLockWithTimeoutThenUnlockOperator.class,
|
||||
TryLockThenUnlockOperator.class);
|
||||
globalMemoryMeasurer.printUsedMemory("Global used memory mesure");
|
||||
}
|
||||
globalMemoryMeasurer.end();
|
||||
|
||||
warmupRound = false;
|
||||
|
||||
globalMemoryMeasurer = new MemoryMeasurer();
|
||||
globalMemoryMeasurer.begin();
|
||||
long usedMemory = 0;
|
||||
for (int i = 0; i < mesureRounds; i++) {
|
||||
launchThreadSafetyTest(locker, nOperatorsByClassOperator, nOperationsByOperator, assertEntriesLessThanCleanPeriod,
|
||||
warmupRound, shutdownAtEnd, LockThenUnlockOperator.class, TryLockWithTimeoutThenUnlockOperator.class,
|
||||
TryLockThenUnlockOperator.class);
|
||||
boolean useGCBeforeMeasure = true;
|
||||
usedMemory = globalMemoryMeasurer.step(useGCBeforeMeasure);
|
||||
globalMemoryMeasurer.printUsedMemory("Global used memory mesure");
|
||||
}
|
||||
|
||||
assertTrue("Used memory exceeds the expected", usedMemory < 200000);
|
||||
|
||||
locker.shutdown();
|
||||
|
||||
usedMemory = globalMemoryMeasurer.end();
|
||||
globalMemoryMeasurer.printUsedMemory("Global used memory mesure after shutdown");
|
||||
|
||||
assertTrue("Used memory exceeds the expected", usedMemory < 20000);
|
||||
|
||||
locker = null;
|
||||
|
||||
usedMemory = globalMemoryMeasurer.end();
|
||||
globalMemoryMeasurer.printUsedMemory("Global used memory mesure after set to null");
|
||||
assertTrue("Used memory exceeds the expected", usedMemory < 20000);
|
||||
|
||||
}
|
||||
|
||||
private void launchThreadSafetyTest(final ILockerByKey locker, final int nOperatorsByClassOperator,
|
||||
final int nOperationsByOperator, boolean assertEntriesLessThanCleanPeriod, boolean warmupRound,
|
||||
final boolean shutdownAtEnd, Class<? extends AbstractLockerByKeyOperator>... classOperators) throws Exception {
|
||||
final ResultContainer resultContainer = new ResultContainer();
|
||||
|
||||
System.out.println("####################################################################################");
|
||||
if (warmupRound) {
|
||||
System.out.println("!!! WARMUP ROUND !!! (don't take account the results of this round)");
|
||||
}
|
||||
|
||||
class LockerThreadSafetyTester extends AbstractThreadSafetyTester<AbstractLockerByKeyOperator> {
|
||||
|
||||
private boolean assertEntriesLessThanCleanPeriod;
|
||||
|
||||
public LockerThreadSafetyTester(int nOperatorsByClassOperator, boolean assertEntriesLessThanCleanPeriod,
|
||||
Class<? extends AbstractLockerByKeyOperator>... classOperators) {
|
||||
super(nOperatorsByClassOperator, classOperators);
|
||||
this.assertEntriesLessThanCleanPeriod = assertEntriesLessThanCleanPeriod;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.talend.commons.utils.threading.AbstractThreadSafetyTester#initInstance(org.talend.commons.utils.threading
|
||||
* .IThreadSafetyOperator)
|
||||
*/
|
||||
protected void initInstance(AbstractLockerByKeyOperator operatorInstance) {
|
||||
operatorInstance.setDebug(DEBUG);
|
||||
operatorInstance.setLocker(locker);
|
||||
operatorInstance.setnOperationsByOperator(nOperationsByOperator);
|
||||
operatorInstance.setResultContainer(resultContainer);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.talend.commons.utils.threading.AbstractThreadSafetyTester#assertFinal()
|
||||
*/
|
||||
@Override
|
||||
protected void assertFinal() {
|
||||
int actualSumLockedAtEnd = 0;
|
||||
int actualSumLockersAtEnd = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
LockerValue lockerValue = locker.getLockerValue(i);
|
||||
if (lockerValue != null) {
|
||||
int queueLength = lockerValue.getLock().getQueueLength();
|
||||
if (lockerValue != null) {
|
||||
actualSumLockedAtEnd += queueLength;
|
||||
}
|
||||
actualSumLockersAtEnd++;
|
||||
}
|
||||
}
|
||||
assertThat(actualSumLockedAtEnd, is(0));
|
||||
if (assertEntriesLessThanCleanPeriod) {
|
||||
assertTrue("actualSumLockersAtEnd > locker.getCleanPeriod() where actualSumLockersAtEnd="
|
||||
+ actualSumLockersAtEnd + " and locker.getCleanPeriod()=" + locker.getCleanPeriod(),
|
||||
actualSumLockersAtEnd < locker.getCleanPeriod());
|
||||
}
|
||||
|
||||
if (shutdownAtEnd) {
|
||||
locker.shutdown();
|
||||
} else {
|
||||
locker.clean();
|
||||
}
|
||||
actualSumLockedAtEnd = 0;
|
||||
actualSumLockersAtEnd = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
LockerValue lockerValue = locker.getLockerValue(i);
|
||||
if (lockerValue != null) {
|
||||
int queueLength = lockerValue.getLock().getQueueLength();
|
||||
if (lockerValue != null) {
|
||||
actualSumLockedAtEnd += queueLength;
|
||||
}
|
||||
actualSumLockersAtEnd++;
|
||||
}
|
||||
}
|
||||
assertThat(actualSumLockedAtEnd, is(0));
|
||||
assertThat(actualSumLockersAtEnd, is(0));
|
||||
|
||||
assertThat(AbstractLockerByKeyOperator.getNotThreadSafeCounter(),
|
||||
is(resultContainer.sumThreadSafeOperations.get()));
|
||||
System.out.println("Total of operations done: " + resultContainer.sumThreadSafeOperations.get());
|
||||
System.out.println("Average duration: "
|
||||
+ ((double) getDuration() / (double) resultContainer.sumThreadSafeOperations.get()) + " ms by operation");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
LockerThreadSafetyTester lockerThreadSafetyTester = new LockerThreadSafetyTester(nOperatorsByClassOperator,
|
||||
assertEntriesLessThanCleanPeriod, classOperators);
|
||||
lockerThreadSafetyTester.start();
|
||||
}
|
||||
}
|
||||
@@ -1,961 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.lockerbykey;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.MethodRule;
|
||||
import org.junit.rules.Timeout;
|
||||
import org.talend.commons.utils.memory.MemoryMeasurer;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.AbstractLockerByKeyOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.CleanOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.LockThenUnlockOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.LockThenUnlockUnrestrictedOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.ResultContainer;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.TryLockThenUnlockOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.TryLockThenUnlockUnrestrictedOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.TryLockWithTimeoutThenUnlockOperator;
|
||||
import org.talend.commons.utils.threading.lockerbykey.operators.TryLockWithTimeoutThenUnlockUnrestrictedOperator;
|
||||
import org.talend.commons.utils.threading.threadsafetester.AbstractThreadSafetyTester;
|
||||
|
||||
public class LockerByKeyUnrestrictedTest extends LockerByKeyTest {
|
||||
|
||||
@Rule
|
||||
public MethodRule globalTimeout = new Timeout(60000);
|
||||
|
||||
private static final int WAIT_THREAD_STARTED = 100;
|
||||
|
||||
private static final int WAIT_JOIN = 100;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
protected ILockerByKey createLockerInstance() {
|
||||
// default implementation when running this TestCase
|
||||
return createLockerUnrestrictedInstance();
|
||||
}
|
||||
|
||||
protected LockerByKeyUnrestricted createLockerUnrestrictedInstance() {
|
||||
// default implementation when running this TestCase
|
||||
return new LockerByKeyUnrestricted();
|
||||
}
|
||||
|
||||
class LockInterruptiblyUnrestrictedThread extends Thread {
|
||||
|
||||
private LockerByKeyUnrestricted locker;
|
||||
|
||||
Integer key;
|
||||
|
||||
public Throwable throwable;
|
||||
|
||||
public LockInterruptiblyUnrestrictedThread(LockerByKeyUnrestricted locker, Integer key) {
|
||||
super();
|
||||
this.locker = locker;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
locker.lockInterruptiblyUnrestricted(key);
|
||||
} catch (Throwable e) {
|
||||
throwable = e;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class LockInterruptiblyUnrestrictedTwiceThread extends Thread {
|
||||
|
||||
private LockerByKeyUnrestricted locker;
|
||||
|
||||
Integer key;
|
||||
|
||||
public Throwable throwable;
|
||||
|
||||
public LockInterruptiblyUnrestrictedTwiceThread(LockerByKeyUnrestricted locker, Integer key) {
|
||||
super();
|
||||
this.locker = locker;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
locker.lockInterruptiblyUnrestricted(key);
|
||||
locker.lockInterruptiblyUnrestricted(key);
|
||||
} catch (Throwable e) {
|
||||
throwable = e;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class UnlockUnrestrictedThread extends Thread {
|
||||
|
||||
private LockerByKeyUnrestricted locker;
|
||||
|
||||
Integer key;
|
||||
|
||||
public Throwable throwable;
|
||||
|
||||
public UnlockUnrestrictedThread(LockerByKeyUnrestricted locker, Integer key) {
|
||||
super();
|
||||
this.locker = locker;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
locker.unlockUnrestricted(key);
|
||||
} catch (Throwable e) {
|
||||
throwable = e;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
// @Test(timeout = 2000)
|
||||
@Test()
|
||||
public void testUnrestricted_IsLocked_with_Lock_then_Unlock() throws Throwable {
|
||||
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
locker.lockInterruptiblyUnrestricted(keyOne);
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
boolean hasUnlocked = locker.unlockUnrestricted(keyOne);
|
||||
assertThat(hasUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_LockWithThread1_and_UnlockWithThread2() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
locker.lockInterruptiblyUnrestricted(keyOne);
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
ExecutorService poolRunnable2 = Executors.newCachedThreadPool();
|
||||
|
||||
// UNLOCK STEP
|
||||
Callable<Boolean> runnableUnlock = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
return locker.unlockUnrestricted(keyOne);
|
||||
}
|
||||
};
|
||||
Future<Boolean> futureUnlock = poolRunnable2.submit(runnableUnlock);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
Boolean resultUnlocked = futureUnlock.get(2, TimeUnit.SECONDS);
|
||||
assertThat(resultUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_TryLockWithThread1_and_UnlockWithThread2() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
boolean locked = locker.tryLockUnrestricted(keyOne);
|
||||
assertThat(locked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
ExecutorService poolRunnable2 = Executors.newCachedThreadPool();
|
||||
|
||||
// UNLOCK STEP
|
||||
Callable<Boolean> runnableUnlock = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
return locker.unlockUnrestricted(keyOne);
|
||||
}
|
||||
};
|
||||
Future<Boolean> futureUnlock = poolRunnable2.submit(runnableUnlock);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
Boolean resultUnlocked = futureUnlock.get(2, TimeUnit.SECONDS);
|
||||
assertThat(resultUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_TryLockTimeoutWithThread1_and_UnlockWithThread2() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
boolean locked = locker.tryLockUnrestricted(keyOne);
|
||||
assertThat(locked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
ExecutorService poolRunnable2 = Executors.newCachedThreadPool();
|
||||
|
||||
// UNLOCK STEP
|
||||
Callable<Boolean> runnableUnlock = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
return locker.unlockUnrestricted(keyOne);
|
||||
}
|
||||
};
|
||||
Future<Boolean> futureUnlock = poolRunnable2.submit(runnableUnlock);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
Boolean resultUnlocked = futureUnlock.get(2, TimeUnit.SECONDS);
|
||||
assertThat(resultUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
// @Test(timeout = 2000)
|
||||
@Test()
|
||||
public void testUnrestricted_LockThread1_then_TryLockTimeoutWithThread2_then_UnlockThread1_then_UnlockWithThread3()
|
||||
throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
// final int baseTimeoutSeconds = 2;
|
||||
final int baseTimeoutSeconds = Integer.MAX_VALUE;
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
// STEP 1
|
||||
locker.lockInterruptiblyUnrestricted(keyOne);
|
||||
|
||||
ExecutorService poolRunnableTryLockTimeout = Executors.newCachedThreadPool();
|
||||
|
||||
// TRY LOCK TIMEOUT STEP
|
||||
Callable<Boolean> runnableTryLockTimeout = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
// STEP 2
|
||||
boolean locked = locker.tryLockUnrestricted(keyOne, baseTimeoutSeconds, TimeUnit.SECONDS);
|
||||
// STEP 4
|
||||
return locked;
|
||||
|
||||
}
|
||||
};
|
||||
Future<Boolean> futureTryLockTimeout = poolRunnableTryLockTimeout.submit(runnableTryLockTimeout);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
// STEP 3
|
||||
boolean unlocked = locker.unlockUnrestricted(keyOne);
|
||||
assertThat(unlocked, is(true));
|
||||
|
||||
// STEP 5
|
||||
Boolean locked = futureTryLockTimeout.get(baseTimeoutSeconds, TimeUnit.SECONDS);
|
||||
assertThat(locked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
ExecutorService poolRunnable2 = Executors.newCachedThreadPool();
|
||||
|
||||
// UNLOCK STEP
|
||||
Callable<Boolean> runnableUnlock = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
// STEP 6
|
||||
return locker.unlockUnrestricted(keyOne);
|
||||
}
|
||||
};
|
||||
Future<Boolean> futureUnlock = poolRunnable2.submit(runnableUnlock);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
// STEP 7
|
||||
Boolean resultUnlocked = futureUnlock.get(baseTimeoutSeconds, TimeUnit.SECONDS);
|
||||
assertThat(resultUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000, expected = IllegalStateException.class)
|
||||
// @Test(expected = IllegalStateException.class)
|
||||
public void testUnrestricted_Unlock_with_noPreviousLock() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
locker.unlockUnrestricted(keyOne);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_CleanEnabledDefault() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
locker.lockInterruptiblyUnrestricted(i);
|
||||
|
||||
isLocked = locker.isLocked(i);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
boolean hasUnlocked = locker.unlockUnrestricted(i);
|
||||
assertThat(hasUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(i);
|
||||
assertThat(isLocked, is(false));
|
||||
}
|
||||
|
||||
/*
|
||||
* Be warn, the last is not removed by the auto clean, need to call clean again to clear all.
|
||||
*/
|
||||
for (int i = 0; i < 999; i++) {
|
||||
assertThat(locker.getLockerValue(i), is(nullValue()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_CleanEnabledProvidedPeriod() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = new LockerByKeyUnrestricted(true, 600);
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
boolean isLocked = locker.isLocked(keyOne);
|
||||
assertThat(isLocked, is(false));
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
locker.lockInterruptiblyUnrestricted(i);
|
||||
|
||||
isLocked = locker.isLocked(i);
|
||||
assertThat(isLocked, is(true));
|
||||
|
||||
boolean hasUnlocked = locker.unlockUnrestricted(i);
|
||||
assertThat(hasUnlocked, is(true));
|
||||
|
||||
isLocked = locker.isLocked(i);
|
||||
assertThat(isLocked, is(false));
|
||||
}
|
||||
|
||||
/*
|
||||
* Be warn, the last is not removed by the auto clean, need to call clean again to clear all.
|
||||
*/
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (i < 600) {
|
||||
assertThat(locker.getLockerValue(i), is(nullValue()));
|
||||
} else {
|
||||
assertThat(locker.getLockerValue(i), is(notNullValue()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_Shutdown_with_waiting_Lock() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
ExecutorService poolRunnable1 = Executors.newCachedThreadPool();
|
||||
ExecutorService poolRunnable2 = Executors.newCachedThreadPool();
|
||||
|
||||
final int keyOne = 1;
|
||||
final String expectedResult = "ended";
|
||||
Callable<String> runnable = new Callable<String>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
locker.lockInterruptiblyUnrestricted(keyOne);
|
||||
return expectedResult;
|
||||
}
|
||||
};
|
||||
|
||||
Future<String> future1 = poolRunnable1.submit(runnable);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
String result1 = future1.get(2, TimeUnit.SECONDS);
|
||||
assertThat(result1, is(expectedResult));
|
||||
poolRunnable1.shutdown();
|
||||
|
||||
Future<String> future2 = poolRunnable2.submit(runnable);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
locker.shutdown();
|
||||
|
||||
try {
|
||||
future2.get(2, TimeUnit.SECONDS);
|
||||
fail("Should be interrupted by the shutdown");
|
||||
} catch (Exception e) {
|
||||
boolean isInterruptedException = e.getCause() instanceof InterruptedException;
|
||||
if (!isInterruptedException) {
|
||||
e.printStackTrace();
|
||||
fail("Should be an InterruptedException, please read logs");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_Shutdown_TryLockWithTimeout() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
ExecutorService poolRunnable1 = Executors.newCachedThreadPool();
|
||||
ExecutorService poolRunnable2 = Executors.newCachedThreadPool();
|
||||
|
||||
final int keyOne = 1;
|
||||
final String expectedResult = "ended";
|
||||
Callable<String> runnable = new Callable<String>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
locker.tryLockUnrestricted(keyOne, 10000);
|
||||
return expectedResult;
|
||||
}
|
||||
};
|
||||
|
||||
Future<String> future1 = poolRunnable1.submit(runnable);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
String result1 = future1.get(2, TimeUnit.SECONDS);
|
||||
assertThat(result1, is(expectedResult));
|
||||
|
||||
Future<String> future2 = poolRunnable2.submit(runnable);
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
|
||||
locker.shutdown();
|
||||
|
||||
try {
|
||||
future2.get(2, TimeUnit.SECONDS);
|
||||
fail("Should be interrupted by the shutdown");
|
||||
} catch (Exception e) {
|
||||
boolean isInterruptedException = e.getCause() instanceof InterruptedException;
|
||||
if (!isInterruptedException) {
|
||||
e.printStackTrace();
|
||||
fail("Should be an InterruptedException, please read logs");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_Unlock_withGetLockerValue() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
|
||||
LockerValue lockerValue = locker.getLockerValue(keyOne);
|
||||
assertThat(lockerValue, is(nullValue()));
|
||||
|
||||
locker.lockInterruptiblyUnrestricted(keyOne);
|
||||
|
||||
LockerValue lockerValue1 = locker.getLockerValue(keyOne);
|
||||
assertThat(lockerValue1, is(notNullValue()));
|
||||
|
||||
boolean hasUnlocked = locker.unlockUnrestricted(keyOne);
|
||||
assertThat(hasUnlocked, is(true));
|
||||
|
||||
LockerValue lockerValue2 = locker.getLockerValue(keyOne);
|
||||
assertThat(lockerValue2, is(lockerValue1));
|
||||
|
||||
locker.shutdown();
|
||||
LockerValue lockerValue3 = locker.getLockerValue(keyOne);
|
||||
assertThat(lockerValue3, is(nullValue()));
|
||||
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_Lock_LockTwiceWithSameKey() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyUnrestrictedThread threadLockKeyOne_first = new LockInterruptiblyUnrestrictedThread(locker, keyOne);
|
||||
threadLockKeyOne_first.start();
|
||||
threadLockKeyOne_first.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_first.isAlive(), is(false));
|
||||
if (threadLockKeyOne_first.throwable != null) {
|
||||
throw threadLockKeyOne_first.throwable;
|
||||
}
|
||||
|
||||
LockInterruptiblyUnrestrictedThread threadLockKeyOne_second = new LockInterruptiblyUnrestrictedThread(locker, keyOne);
|
||||
threadLockKeyOne_second.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(true));
|
||||
threadLockKeyOne_second.interrupt();
|
||||
threadLockKeyOne_second.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(false));
|
||||
assertThat(threadLockKeyOne_second.throwable, is(notNullValue()));
|
||||
assertThat(threadLockKeyOne_second.throwable, is(instanceOf(InterruptedException.class)));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_Lock_LockTwiceWithSamePrimitiveValueButDifferentInteger() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
final Integer keyOneInteger1 = new Integer(keyOne);
|
||||
LockInterruptiblyUnrestrictedThread threadLockKeyOne_first = new LockInterruptiblyUnrestrictedThread(locker,
|
||||
keyOneInteger1);
|
||||
threadLockKeyOne_first.start();
|
||||
threadLockKeyOne_first.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_first.isAlive(), is(false));
|
||||
if (threadLockKeyOne_first.throwable != null) {
|
||||
throw threadLockKeyOne_first.throwable;
|
||||
}
|
||||
|
||||
final Integer keyOneInteger2 = new Integer(keyOne);
|
||||
LockInterruptiblyUnrestrictedThread threadLockKeyOne_second = new LockInterruptiblyUnrestrictedThread(locker,
|
||||
keyOneInteger2);
|
||||
threadLockKeyOne_second.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(true));
|
||||
threadLockKeyOne_second.interrupt();
|
||||
threadLockKeyOne_second.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(false));
|
||||
assertThat(threadLockKeyOne_second.throwable, is(notNullValue()));
|
||||
assertThat(threadLockKeyOne_second.throwable, is(instanceOf(InterruptedException.class)));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
public void testUnrestricted_Lock_LockTwiceWithDifferentKeys() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyUnrestrictedThread threadLockKeyOne_first = new LockInterruptiblyUnrestrictedThread(locker, keyOne);
|
||||
threadLockKeyOne_first.start();
|
||||
threadLockKeyOne_first.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_first.isAlive(), is(false));
|
||||
if (threadLockKeyOne_first.throwable != null) {
|
||||
throw threadLockKeyOne_first.throwable;
|
||||
}
|
||||
|
||||
final int keyTwo = 2;
|
||||
LockInterruptiblyUnrestrictedThread threadLockKeyOne_second = new LockInterruptiblyUnrestrictedThread(locker, keyTwo);
|
||||
threadLockKeyOne_second.start();
|
||||
threadLockKeyOne_second.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne_second.isAlive(), is(false));
|
||||
if (threadLockKeyOne_first.throwable != null) {
|
||||
throw threadLockKeyOne_first.throwable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test
|
||||
public void testUnrestricted_Lock_ThenUnlockFromOtherThread() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyUnrestrictedThread threadLockKeyOne = new LockInterruptiblyUnrestrictedThread(locker, keyOne);
|
||||
threadLockKeyOne.start();
|
||||
threadLockKeyOne.join(WAIT_JOIN);
|
||||
assertThat(threadLockKeyOne.isAlive(), is(false));
|
||||
if (threadLockKeyOne.throwable != null) {
|
||||
throw threadLockKeyOne.throwable;
|
||||
}
|
||||
|
||||
UnlockUnrestrictedThread threadUnlockKeyOne = new UnlockUnrestrictedThread(locker, keyOne);
|
||||
threadUnlockKeyOne.start();
|
||||
threadUnlockKeyOne.join(WAIT_JOIN);
|
||||
assertThat(threadUnlockKeyOne.isAlive(), is(false));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_Lock_LockTwiceFromDifferentThread() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyUnrestrictedThread threadLock_threadOne = new LockInterruptiblyUnrestrictedThread(locker, keyOne);
|
||||
threadLock_threadOne.start();
|
||||
threadLock_threadOne.join(WAIT_JOIN);
|
||||
assertThat(threadLock_threadOne.isAlive(), is(false));
|
||||
if (threadLock_threadOne.throwable != null) {
|
||||
throw threadLock_threadOne.throwable;
|
||||
}
|
||||
|
||||
LockInterruptiblyUnrestrictedThread threadLock_threadTwo = new LockInterruptiblyUnrestrictedThread(locker, keyOne);
|
||||
threadLock_threadTwo.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
threadLock_threadTwo.interrupt();
|
||||
assertThat(threadLock_threadTwo.isAlive(), is(true));
|
||||
threadLock_threadTwo.join(WAIT_JOIN);
|
||||
assertThat(threadLock_threadTwo.isAlive(), is(false));
|
||||
assertThat(threadLock_threadTwo.throwable, is(notNullValue()));
|
||||
assertThat(threadLock_threadTwo.throwable, is(instanceOf(InterruptedException.class)));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_Lock_LockTwiceFromSameThread_allowReentrantLockFromOtherThread() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyUnrestrictedTwiceThread threadLockTwiceKeyOne = new LockInterruptiblyUnrestrictedTwiceThread(locker,
|
||||
keyOne);
|
||||
threadLockTwiceKeyOne.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertThat(threadLockTwiceKeyOne.isAlive(), is(false));
|
||||
assertThat(threadLockTwiceKeyOne.throwable, is(nullValue()));
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
// @Test()
|
||||
public void testUnrestricted_Lock_LockTwiceFromDifferentThread_forbidReentrantLockFromLockerThread() throws Throwable {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
|
||||
final int keyOne = 1;
|
||||
LockInterruptiblyUnrestrictedThread threadLock_threadOne = new LockInterruptiblyUnrestrictedThread(locker, keyOne);
|
||||
threadLock_threadOne.start();
|
||||
threadLock_threadOne.join(WAIT_JOIN);
|
||||
assertThat(threadLock_threadOne.isAlive(), is(false));
|
||||
if (threadLock_threadOne.throwable != null) {
|
||||
throw threadLock_threadOne.throwable;
|
||||
}
|
||||
|
||||
LockInterruptiblyUnrestrictedThread threadLock_threadTwo = new LockInterruptiblyUnrestrictedThread(locker, keyOne);
|
||||
threadLock_threadTwo.start();
|
||||
Thread.sleep(WAIT_THREAD_STARTED);
|
||||
assertThat(threadLock_threadTwo.isAlive(), is(true));
|
||||
threadLock_threadTwo.interrupt();
|
||||
threadLock_threadTwo.join(WAIT_JOIN);
|
||||
assertThat(threadLock_threadTwo.isAlive(), is(false));
|
||||
assertThat(threadLock_threadTwo.throwable, is(notNullValue()));
|
||||
assertThat(threadLock_threadTwo.throwable, is(instanceOf(InterruptedException.class)));
|
||||
}
|
||||
|
||||
@Test(timeout = 1000)
|
||||
// @Test
|
||||
public void testUnrestricted_GetSuspectLocks() throws Exception {
|
||||
LockerByKeyUnrestricted<Integer> locker = createLockerUnrestrictedInstance();
|
||||
locker.setDetectSuspectLocks(true);
|
||||
int keyOne = 1;
|
||||
|
||||
locker.lockInterruptibly(keyOne);
|
||||
List<LockerValue<Integer>> suspectLocks = locker.getSuspectLocks(1000);
|
||||
assertThat(suspectLocks.size(), is(0));
|
||||
|
||||
Thread.sleep(100);
|
||||
suspectLocks = locker.getSuspectLocks(50);
|
||||
assertThat(suspectLocks.size(), is(1));
|
||||
|
||||
locker.unlock(keyOne);
|
||||
suspectLocks = locker.getSuspectLocks(50);
|
||||
assertThat(suspectLocks.size(), is(0));
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
// @Test
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void testUnrestricted_ThreadSafety_LockThenUnlock_TryLockTimeoutThenUnlock_TryLockThenUnlock_autoClean()
|
||||
throws Exception {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
final int nOperatorsByClassOperator = 30;
|
||||
final int nOperationsByOperator = 250;
|
||||
boolean assertEntriesLessThanCleanPeriod = true;
|
||||
boolean shutdownAtEnd = true;
|
||||
boolean warmupRound = false;
|
||||
launchThreadSafetyTest(locker, nOperatorsByClassOperator, nOperationsByOperator, assertEntriesLessThanCleanPeriod,
|
||||
warmupRound, shutdownAtEnd, LockThenUnlockOperator.class, TryLockWithTimeoutThenUnlockOperator.class,
|
||||
TryLockThenUnlockOperator.class);
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
// @Test
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void testUnrestricted_ThreadSafety_LockThenUnlock_TryLockTimeoutThenUnlock_TryLockThenUnlock_with_randomClean()
|
||||
throws Exception {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
final int nOperatorsByClassOperator = 30;
|
||||
final int nOperationsByOperator = 250;
|
||||
boolean assertEntriesLessThanCleanPeriod = true;
|
||||
boolean shutdownAtEnd = true;
|
||||
boolean warmupRound = false;
|
||||
launchThreadSafetyTest(locker, nOperatorsByClassOperator, nOperationsByOperator, assertEntriesLessThanCleanPeriod,
|
||||
warmupRound, shutdownAtEnd, LockThenUnlockOperator.class, TryLockWithTimeoutThenUnlockOperator.class,
|
||||
TryLockThenUnlockOperator.class, CleanOperator.class);
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
// @Test
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void testUnrestricted_ThreadSafety_LockThenUnlock_TryLockTimeoutThenUnlock_TryLockThenUnlock_with_randomClean_mixedRestrictedUnrestricted()
|
||||
throws Exception {
|
||||
final LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
final int nOperatorsByClassOperator = 30;
|
||||
final int nOperationsByOperator = 250;
|
||||
boolean assertEntriesLessThanCleanPeriod = true;
|
||||
boolean shutdownAtEnd = true;
|
||||
boolean warmupRound = false;
|
||||
launchThreadSafetyTest(locker, nOperatorsByClassOperator, nOperationsByOperator, assertEntriesLessThanCleanPeriod,
|
||||
warmupRound, shutdownAtEnd, LockThenUnlockOperator.class, LockThenUnlockUnrestrictedOperator.class,
|
||||
TryLockWithTimeoutThenUnlockOperator.class, TryLockWithTimeoutThenUnlockUnrestrictedOperator.class,
|
||||
TryLockThenUnlockOperator.class, TryLockThenUnlockUnrestrictedOperator.class, CleanOperator.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to show the increasing memory with old Locker and stable memory with new LockerByKey
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test(timeout = 30000)
|
||||
// @Test
|
||||
public void testUnrestricted_Memory() throws Exception {
|
||||
LockerByKeyUnrestricted locker = createLockerUnrestrictedInstance();
|
||||
final int nOperatorsByClassOperator = 30;
|
||||
final int nOperationsByOperator = 50;
|
||||
boolean assertEntriesLessThanCleanPeriod = true;
|
||||
boolean warmupRound = true;
|
||||
boolean shutdownAtEnd = false;
|
||||
int warmupRounds = 3;
|
||||
int mesureRounds = 3;
|
||||
|
||||
MemoryMeasurer globalMemoryMeasurer = new MemoryMeasurer();
|
||||
globalMemoryMeasurer.begin();
|
||||
for (int i = 0; i < warmupRounds; i++) {
|
||||
launchThreadSafetyTest(locker, nOperatorsByClassOperator, nOperationsByOperator, assertEntriesLessThanCleanPeriod,
|
||||
warmupRound, shutdownAtEnd, LockThenUnlockOperator.class, TryLockWithTimeoutThenUnlockOperator.class,
|
||||
TryLockThenUnlockOperator.class);
|
||||
globalMemoryMeasurer.printUsedMemory("Global used memory mesure");
|
||||
}
|
||||
globalMemoryMeasurer.end();
|
||||
|
||||
warmupRound = false;
|
||||
|
||||
globalMemoryMeasurer = new MemoryMeasurer();
|
||||
globalMemoryMeasurer.begin();
|
||||
long usedMemory = 0;
|
||||
for (int i = 0; i < mesureRounds; i++) {
|
||||
launchThreadSafetyTest(locker, nOperatorsByClassOperator, nOperationsByOperator, assertEntriesLessThanCleanPeriod,
|
||||
warmupRound, shutdownAtEnd, LockThenUnlockOperator.class, TryLockWithTimeoutThenUnlockOperator.class,
|
||||
TryLockThenUnlockOperator.class);
|
||||
boolean useGCBeforeMeasure = true;
|
||||
usedMemory = globalMemoryMeasurer.step(useGCBeforeMeasure);
|
||||
globalMemoryMeasurer.printUsedMemory("Global used memory mesure");
|
||||
}
|
||||
|
||||
assertTrue("Used memory exceeds the expected", usedMemory < 300000);
|
||||
|
||||
locker.shutdown();
|
||||
|
||||
usedMemory = globalMemoryMeasurer.end();
|
||||
globalMemoryMeasurer.printUsedMemory("Global used memory mesure after shutdown");
|
||||
|
||||
assertTrue("Used memory exceeds the expected", usedMemory < 50000);
|
||||
|
||||
locker = null;
|
||||
|
||||
usedMemory = globalMemoryMeasurer.end();
|
||||
globalMemoryMeasurer.printUsedMemory("Global used memory mesure after set to null");
|
||||
assertTrue("Used memory exceeds the expected", usedMemory < 50000);
|
||||
|
||||
}
|
||||
|
||||
private void launchThreadSafetyTest(final ILockerByKey locker, final int nOperatorsByClassOperator,
|
||||
final int nOperationsByOperator, boolean assertEntriesLessThanCleanPeriod, boolean warmupRound,
|
||||
final boolean shutdownAtEnd, Class<? extends AbstractLockerByKeyOperator>... classOperators) throws Exception {
|
||||
final ResultContainer resultContainer = new ResultContainer();
|
||||
|
||||
System.out.println("####################################################################################");
|
||||
if (warmupRound) {
|
||||
System.out.println("!!! WARMUP ROUND !!! (don't take account the results of this round)");
|
||||
}
|
||||
class LockerThreadSafetyTester extends AbstractThreadSafetyTester<AbstractLockerByKeyOperator> {
|
||||
|
||||
private boolean assertEntriesLessThanCleanPeriod;
|
||||
|
||||
public LockerThreadSafetyTester(int nOperatorsByClassOperator, boolean assertEntriesLessThanCleanPeriod,
|
||||
Class<? extends AbstractLockerByKeyOperator>... classOperators) {
|
||||
super(nOperatorsByClassOperator, classOperators);
|
||||
this.assertEntriesLessThanCleanPeriod = assertEntriesLessThanCleanPeriod;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.talend.commons.utils.threading.AbstractThreadSafetyTester#initInstance(org.talend.commons.utils.threading
|
||||
* .IThreadSafetyOperator)
|
||||
*/
|
||||
protected void initInstance(AbstractLockerByKeyOperator operatorInstance) {
|
||||
operatorInstance.setDebug(DEBUG);
|
||||
operatorInstance.setLocker(locker);
|
||||
operatorInstance.setnOperationsByOperator(nOperationsByOperator);
|
||||
operatorInstance.setResultContainer(resultContainer);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.talend.commons.utils.threading.AbstractThreadSafetyTester#assertFinal()
|
||||
*/
|
||||
@Override
|
||||
protected void assertFinal() {
|
||||
int actualSumLockedAtEnd = 0;
|
||||
int actualSumLockersAtEnd = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
LockerValue lockerValue = locker.getLockerValue(i);
|
||||
if (lockerValue != null) {
|
||||
int queueLength = lockerValue.getLock().getQueueLength();
|
||||
if (lockerValue != null) {
|
||||
actualSumLockedAtEnd += queueLength;
|
||||
}
|
||||
actualSumLockersAtEnd++;
|
||||
}
|
||||
}
|
||||
assertThat(actualSumLockedAtEnd, is(0));
|
||||
if (assertEntriesLessThanCleanPeriod) {
|
||||
assertTrue("actualSumLockersAtEnd > locker.getCleanPeriod() where actualSumLockersAtEnd="
|
||||
+ actualSumLockersAtEnd + " and locker.getCleanPeriod()=" + locker.getCleanPeriod(),
|
||||
actualSumLockersAtEnd < locker.getCleanPeriod());
|
||||
}
|
||||
|
||||
if (shutdownAtEnd) {
|
||||
locker.shutdown();
|
||||
} else {
|
||||
locker.clean();
|
||||
}
|
||||
actualSumLockedAtEnd = 0;
|
||||
actualSumLockersAtEnd = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
LockerValue lockerValue = locker.getLockerValue(i);
|
||||
if (lockerValue != null) {
|
||||
int queueLength = lockerValue.getLock().getQueueLength();
|
||||
if (lockerValue != null) {
|
||||
actualSumLockedAtEnd += queueLength;
|
||||
}
|
||||
actualSumLockersAtEnd++;
|
||||
}
|
||||
}
|
||||
assertThat(actualSumLockedAtEnd, is(0));
|
||||
assertThat(actualSumLockersAtEnd, is(0));
|
||||
|
||||
assertThat(AbstractLockerByKeyOperator.getNotThreadSafeCounter(),
|
||||
is(resultContainer.sumThreadSafeOperations.get()));
|
||||
System.out.println("Total of operations done: " + resultContainer.sumThreadSafeOperations.get());
|
||||
System.out.println("Average duration: "
|
||||
+ ((double) getDuration() / (double) resultContainer.sumThreadSafeOperations.get()) + " ms by operation");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
LockerThreadSafetyTester lockerThreadSafetyTester = new LockerThreadSafetyTester(nOperatorsByClassOperator,
|
||||
assertEntriesLessThanCleanPeriod, classOperators);
|
||||
lockerThreadSafetyTester.start();
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.lockerbykey.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.lockerbykey.ILockerByKey;
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
|
||||
public abstract class AbstractLockerByKeyOperator implements IThreadSafetyOperator {
|
||||
|
||||
protected ILockerByKey locker;
|
||||
|
||||
protected int nOperationsByOperator;
|
||||
|
||||
protected ResultContainer resultContainer;
|
||||
|
||||
protected boolean debug;
|
||||
|
||||
private static int[] notThreadSafeCounters;
|
||||
|
||||
public AbstractLockerByKeyOperator() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for debug.
|
||||
*
|
||||
* @return the debug
|
||||
*/
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the debug.
|
||||
*
|
||||
* @param debug the debug to set
|
||||
*/
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locker.
|
||||
*
|
||||
* @param locker the locker to set
|
||||
*/
|
||||
public void setLocker(ILockerByKey locker) {
|
||||
this.locker = locker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nOperationsByOperator.
|
||||
*
|
||||
* @param nOperationsByOperator the nOperationsByOperator to set
|
||||
*/
|
||||
public void setnOperationsByOperator(int nOperationsByOperator) {
|
||||
this.nOperationsByOperator = nOperationsByOperator;
|
||||
notThreadSafeCounters = new int[nOperationsByOperator];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resultContainer.
|
||||
*
|
||||
* @param resultContainer the resultContainer to set
|
||||
*/
|
||||
public void setResultContainer(ResultContainer resultContainer) {
|
||||
this.resultContainer = resultContainer;
|
||||
}
|
||||
|
||||
public static int getNotThreadSafeCounter() {
|
||||
int counter = 0;
|
||||
for (int i = 0; i < notThreadSafeCounters.length; i++) {
|
||||
counter += notThreadSafeCounters[i];
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
protected void incrementNotThreadSafeCounter(int i) {
|
||||
notThreadSafeCounters[i]++;
|
||||
}
|
||||
|
||||
public String getThreadId() {
|
||||
return "[Thread " + Thread.currentThread().getId() + "] ";
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
return "[" + System.currentTimeMillis() + "] ";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package org.talend.commons.utils.threading.lockerbykey.operators;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class CleanOperator extends AbstractLockerByKeyOperator implements IThreadSafetyOperator {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doOperations() throws Exception {
|
||||
Random random = new Random(System.currentTimeMillis());
|
||||
int nOperationsByOperatorLocal = nOperationsByOperator / 10;
|
||||
for (int i = 0; i < nOperationsByOperatorLocal; i++) {
|
||||
int nextInt = random.nextInt(500);
|
||||
Thread.sleep(nextInt);
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + "Cleaning ...");
|
||||
}
|
||||
locker.clean();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package org.talend.commons.utils.threading.lockerbykey.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class LockThenUnlockOperator extends AbstractLockerByKeyOperator implements IThreadSafetyOperator {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doOperations() throws Exception {
|
||||
int sumThreadSafeOperations = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
try {
|
||||
locker.lockInterruptibly(i);
|
||||
incrementNotThreadSafeCounter(i);
|
||||
sumThreadSafeOperations++;
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": Locked " + i);
|
||||
}
|
||||
Thread.sleep(10);
|
||||
} finally {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": Unlocking " + i);
|
||||
}
|
||||
try {
|
||||
locker.unlock(i);
|
||||
} catch (Exception e) {
|
||||
System.out.println(getTime() + getThreadId() + ": Error when Unlocking " + i);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
resultContainer.sumThreadSafeOperations.getAndAdd(sumThreadSafeOperations);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.talend.commons.utils.threading.lockerbykey.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.lockerbykey.LockerByKeyUnrestricted;
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class LockThenUnlockUnrestrictedOperator extends AbstractLockerByKeyOperator implements IThreadSafetyOperator {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doOperations() throws Exception {
|
||||
int sumThreadSafeOperations = 0;
|
||||
LockerByKeyUnrestricted locker = (LockerByKeyUnrestricted) this.locker;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
try {
|
||||
locker.lockInterruptiblyUnrestricted(i);
|
||||
incrementNotThreadSafeCounter(i);
|
||||
sumThreadSafeOperations++;
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": Locked Unrestricted " + i);
|
||||
}
|
||||
Thread.sleep(10);
|
||||
} finally {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": Unlocking Unrestricted " + i);
|
||||
}
|
||||
try {
|
||||
locker.unlockUnrestricted(i);
|
||||
} catch (Exception e) {
|
||||
System.out.println(getTime() + getThreadId() + ": Error when Unlocking Unrestricted " + i);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
resultContainer.sumThreadSafeOperations.getAndAdd(sumThreadSafeOperations);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.lockerbykey.operators;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ResultContainer {
|
||||
|
||||
public final AtomicInteger sumThreadSafeOperations = new AtomicInteger(0);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package org.talend.commons.utils.threading.lockerbykey.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class TryLockThenUnlockOperator extends AbstractLockerByKeyOperator implements IThreadSafetyOperator {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doOperations() throws Exception {
|
||||
int sumThreadSafeOperations = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
if (locker.tryLock(i)) {
|
||||
incrementNotThreadSafeCounter(i);
|
||||
sumThreadSafeOperations++;
|
||||
try {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLock Locked " + i);
|
||||
}
|
||||
Thread.sleep(10);
|
||||
} finally {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLock Unlocking " + i);
|
||||
}
|
||||
try {
|
||||
locker.unlock(i);
|
||||
} catch (Exception e) {
|
||||
System.out.println(getTime() + getThreadId() + ": Error when Unlocking TryLock Timeout " + i);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLock Timeout Failed " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultContainer.sumThreadSafeOperations.getAndAdd(sumThreadSafeOperations);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package org.talend.commons.utils.threading.lockerbykey.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.lockerbykey.LockerByKeyUnrestricted;
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class TryLockThenUnlockUnrestrictedOperator extends AbstractLockerByKeyOperator implements IThreadSafetyOperator {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doOperations() throws Exception {
|
||||
int sumThreadSafeOperations = 0;
|
||||
LockerByKeyUnrestricted locker = (LockerByKeyUnrestricted) this.locker;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
if (locker.tryLockUnrestricted(i)) {
|
||||
incrementNotThreadSafeCounter(i);
|
||||
sumThreadSafeOperations++;
|
||||
try {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLockUnrestricted Locked " + i);
|
||||
}
|
||||
Thread.sleep(10);
|
||||
} finally {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLockUnrestricted Unlocking " + i);
|
||||
}
|
||||
try {
|
||||
locker.unlockUnrestricted(i);
|
||||
} catch (Exception e) {
|
||||
System.out.println(getTime() + getThreadId() + ": Error when Unlocking TryLockUnrestricted " + i);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLockUnrestricted Failed " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultContainer.sumThreadSafeOperations.getAndAdd(sumThreadSafeOperations);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package org.talend.commons.utils.threading.lockerbykey.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class TryLockWithTimeoutThenUnlockOperator extends AbstractLockerByKeyOperator implements IThreadSafetyOperator {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doOperations() throws Exception {
|
||||
int sumThreadSafeOperations = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
if (locker.tryLock(i, i)) {
|
||||
incrementNotThreadSafeCounter(i);
|
||||
sumThreadSafeOperations++;
|
||||
try {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLock Timeout Locked " + i);
|
||||
}
|
||||
Thread.sleep(10);
|
||||
} finally {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLock Timeout Unlocking " + i);
|
||||
}
|
||||
try {
|
||||
locker.unlock(i);
|
||||
} catch (Exception e) {
|
||||
System.out.println(getTime() + getThreadId() + ": Error when Unlocking TryLock Timeout " + i);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLock Timeout Failed " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultContainer.sumThreadSafeOperations.getAndAdd(sumThreadSafeOperations);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package org.talend.commons.utils.threading.lockerbykey.operators;
|
||||
|
||||
import org.talend.commons.utils.threading.threadsafetester.IThreadSafetyOperator;
|
||||
|
||||
public class TryLockWithTimeoutThenUnlockUnrestrictedOperator extends AbstractLockerByKeyOperator implements IThreadSafetyOperator {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void doOperations() throws Exception {
|
||||
int sumThreadSafeOperations = 0;
|
||||
for (int i = 0; i < nOperationsByOperator; i++) {
|
||||
if (locker.tryLock(i, i)) {
|
||||
incrementNotThreadSafeCounter(i);
|
||||
sumThreadSafeOperations++;
|
||||
try {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLockUnrestricted Timeout Locked " + i);
|
||||
}
|
||||
Thread.sleep(10);
|
||||
} finally {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLockUnrestricted Timeout Unlocking " + i);
|
||||
}
|
||||
try {
|
||||
locker.unlock(i);
|
||||
} catch (Exception e) {
|
||||
System.out.println(getTime() + getThreadId() + ": Error when Unlocking TryLockUnrestricted Timeout " + i);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (debug) {
|
||||
System.out.println(getTime() + getThreadId() + ": TryLockUnrestricted Timeout Failed " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultContainer.sumThreadSafeOperations.getAndAdd(sumThreadSafeOperations);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.threadsafetester;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
*
|
||||
* DOC amaumont class global comment. Detailled comment
|
||||
*
|
||||
* @param T
|
||||
*/
|
||||
public abstract class AbstractThreadSafetyTester<T extends IThreadSafetyOperator> {
|
||||
|
||||
private final ExecutorService pool = Executors.newCachedThreadPool();
|
||||
|
||||
private final CyclicBarrier barrier;
|
||||
|
||||
protected int nOperatorsByClassOperator;
|
||||
|
||||
protected Class<? extends T>[] classOperators;
|
||||
|
||||
private long duration;
|
||||
|
||||
public AbstractThreadSafetyTester(int nOperatorsByClassOperator, Class<? extends T>... classOperators) {
|
||||
this.nOperatorsByClassOperator = nOperatorsByClassOperator;
|
||||
this.classOperators = classOperators;
|
||||
this.barrier = new CyclicBarrier(nOperatorsByClassOperator * classOperators.length + 1);
|
||||
}
|
||||
|
||||
public void start() throws Exception {
|
||||
List<Future<Object>> operatorsHandlerList = new ArrayList<Future<Object>>();
|
||||
try {
|
||||
for (int i = 0; i < nOperatorsByClassOperator; i++) {
|
||||
for (int j = 0; j < classOperators.length; j++) {
|
||||
Class<? extends T> classOperator = classOperators[j];
|
||||
String className = classOperator.getName();
|
||||
Class<? extends T> operator = (Class<? extends T>) Class.forName(className).asSubclass(
|
||||
IThreadSafetyOperator.class);
|
||||
T operatorInstance = operator.newInstance();
|
||||
initInstance(operatorInstance);
|
||||
ThreadSafetyOperatorHandler threadSafetyOperatorHandler = new ThreadSafetyOperatorHandler(operatorInstance);
|
||||
Future futureTask = pool.submit(threadSafetyOperatorHandler);
|
||||
operatorsHandlerList.add(futureTask);
|
||||
}
|
||||
}
|
||||
barrier.await(); // wait for all threads to be ready
|
||||
long start = System.currentTimeMillis();
|
||||
barrier.await(); // wait for all threads to finish
|
||||
duration = System.currentTimeMillis() - start;
|
||||
System.out.println("ThreadSafetyTester duration: " + duration + " ms");
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
int operatorsHandlerListListSize = operatorsHandlerList.size();
|
||||
for (int i = 0; i < operatorsHandlerListListSize; i++) {
|
||||
Future<Object> futureTask = operatorsHandlerList.get(i);
|
||||
try {
|
||||
futureTask.get();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
pool.shutdown();
|
||||
}
|
||||
assertFinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for duration.
|
||||
*
|
||||
* @return the duration
|
||||
*/
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
protected abstract void initInstance(T operatorInstance);
|
||||
|
||||
protected abstract void assertFinal();
|
||||
|
||||
public class ThreadSafetyOperatorHandler<A extends IThreadSafetyOperator> implements Callable<Object> {
|
||||
|
||||
private A operatorInstance;
|
||||
|
||||
public ThreadSafetyOperatorHandler(A operatorInstance) {
|
||||
super();
|
||||
this.operatorInstance = operatorInstance;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
try {
|
||||
barrier.await();
|
||||
operatorInstance.doOperations();
|
||||
} finally {
|
||||
barrier.await();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.threadsafetester;
|
||||
|
||||
|
||||
public interface IThreadSafetyOperator {
|
||||
|
||||
public void doOperations() throws Exception;
|
||||
|
||||
}
|
||||
@@ -24,7 +24,6 @@ Export-Package: org.talend.commons,
|
||||
org.talend.commons.utils.encoding,
|
||||
org.talend.commons.utils.generation,
|
||||
org.talend.commons.utils.io,
|
||||
org.talend.commons.utils.memory,
|
||||
org.talend.commons.utils.network,
|
||||
org.talend.commons.utils.performance,
|
||||
org.talend.commons.utils.platform,
|
||||
@@ -32,7 +31,6 @@ Export-Package: org.talend.commons,
|
||||
org.talend.commons.utils.scalability,
|
||||
org.talend.commons.utils.system,
|
||||
org.talend.commons.utils.threading,
|
||||
org.talend.commons.utils.threading.lockerbykey,
|
||||
org.talend.commons.utils.time,
|
||||
org.talend.commons.utils.tracer,
|
||||
org.talend.commons.utils.workbench.extensions,
|
||||
|
||||
@@ -41,8 +41,6 @@ public class CommonsPlugin extends Plugin {
|
||||
|
||||
private static boolean isSameProjectLogonCommline = false;
|
||||
|
||||
private static boolean useCommandLineRepository = false;
|
||||
|
||||
public static boolean isStoreLibsInWorkspace() {
|
||||
return storeLibsInWorkspace;
|
||||
}
|
||||
@@ -51,14 +49,6 @@ public class CommonsPlugin extends Plugin {
|
||||
CommonsPlugin.storeLibsInWorkspace = storeLibsInWorkspace;
|
||||
}
|
||||
|
||||
public static boolean isUseCommandLineRepository() {
|
||||
return useCommandLineRepository;
|
||||
}
|
||||
|
||||
public static void setUseCommandLineRepository(boolean useCommandLineRepository) {
|
||||
CommonsPlugin.useCommandLineRepository = useCommandLineRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*/
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
package org.talend.commons.utils.memory;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
/**
|
||||
* class MemoryMeasurer.
|
||||
*
|
||||
* It is used to know the difference between the used memory at beginning and at end of measure.
|
||||
*/
|
||||
public class MemoryMeasurer {
|
||||
|
||||
private Long usedMemoryAtBeginning;
|
||||
|
||||
private Long usedMemoryAtEnd;
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "begin".
|
||||
*
|
||||
* It defines the reference of the used memory.
|
||||
*/
|
||||
public void begin() {
|
||||
boolean useGCBeforeMeasure = true;
|
||||
begin(useGCBeforeMeasure);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "begin".
|
||||
*
|
||||
* It defines the reference of the used memory.
|
||||
*
|
||||
* @param useGCBeforeMeasure true to force gc
|
||||
*/
|
||||
public void begin(boolean useGCBeforeMeasure) {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
if (useGCBeforeMeasure) {
|
||||
runtime.gc();
|
||||
}
|
||||
usedMemoryAtBeginning = runtime.totalMemory() - runtime.freeMemory();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "step".
|
||||
*
|
||||
* @param useGCBeforeMeasure true to force gc
|
||||
* @return the difference between the used memory at beginning and at end of measure
|
||||
*/
|
||||
public long step() {
|
||||
boolean useGCBeforeMeasure = false;
|
||||
return step(useGCBeforeMeasure);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "step".
|
||||
*
|
||||
* @param useGCBeforeMeasure true to force gc
|
||||
* @return the difference between the used memory at beginning and at end of measure
|
||||
*/
|
||||
public long step(boolean useGCBeforeMeasure) {
|
||||
if (usedMemoryAtBeginning == null) {
|
||||
throw new IllegalStateException("The method begin must be called first.");
|
||||
}
|
||||
if (useGCBeforeMeasure) {
|
||||
System.gc();
|
||||
}
|
||||
return getUsedMemoryFromBeginToCurrent(false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "end".
|
||||
*
|
||||
* @return the difference between the used memory at beginning and at end of measure
|
||||
*/
|
||||
public long end() {
|
||||
boolean useGCBeforeMeasure = true;
|
||||
return end(useGCBeforeMeasure);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "end".
|
||||
*
|
||||
* @param useGCBeforeMeasure true to force gc
|
||||
* @return the difference between the used memory at beginning and at end of measure
|
||||
*/
|
||||
public long end(boolean useGCBeforeMeasure) {
|
||||
if (usedMemoryAtBeginning == null) {
|
||||
throw new IllegalStateException("The method begin must be called first.");
|
||||
}
|
||||
if (useGCBeforeMeasure) {
|
||||
System.gc();
|
||||
}
|
||||
if (usedMemoryAtEnd == null) {
|
||||
return getUsedMemoryFromBeginToCurrent(true);
|
||||
} else {
|
||||
return getUsedMemoryFromBeginToCurrent(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "printUsedMemory".
|
||||
*
|
||||
*/
|
||||
public void printUsedMemory() {
|
||||
printUsedMemory(null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "printUsedMemory".
|
||||
*
|
||||
*/
|
||||
public void printUsedMemory(String contextInfo) {
|
||||
callMultipleGC();
|
||||
String formated = String.format("%,d", getUsedMemoryFromBeginToCurrent(false));
|
||||
System.out.println((contextInfo != null ? contextInfo + " : " : "") + formated + " bytes");
|
||||
}
|
||||
|
||||
private long getUsedMemoryFromBeginToCurrent(boolean isEndStep) {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
Long usedMemory = usedMemoryAtEnd;
|
||||
if (usedMemory == null || isEndStep) {
|
||||
usedMemory = runtime.totalMemory() - runtime.freeMemory();
|
||||
if (isEndStep) {
|
||||
usedMemoryAtEnd = usedMemory;
|
||||
}
|
||||
}
|
||||
return usedMemory - usedMemoryAtBeginning;
|
||||
}
|
||||
|
||||
private void callMultipleGC() {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
runtime.gc();
|
||||
// runtime.gc();
|
||||
// runtime.gc();
|
||||
// runtime.gc();
|
||||
// runtime.gc();
|
||||
// runtime.gc();
|
||||
// runtime.gc();
|
||||
// runtime.gc();
|
||||
// runtime.gc();
|
||||
// runtime.gc();
|
||||
// runtime.gc();
|
||||
}
|
||||
|
||||
public void printInformations() {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
runtime.gc();
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
long maxMemory = runtime.maxMemory();
|
||||
long allocatedMemory = runtime.totalMemory();
|
||||
long freeMemory = runtime.freeMemory();
|
||||
|
||||
sb.append("Free memory: " + format.format(freeMemory / 1024) + " KB (" + format.format(freeMemory) + ") " + freeMemory
|
||||
+ "\n");
|
||||
sb.append("Allocated memory: " + format.format(allocatedMemory / 1024) + " KB (" + format.format(allocatedMemory)
|
||||
+ ")\n");
|
||||
sb.append("Max memory: " + format.format(maxMemory / 1024) + " KB (" + format.format(maxMemory) + ")\n");
|
||||
sb.append("Total free memory: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024) + " KB ("
|
||||
+ format.format(freeMemory + (maxMemory - allocatedMemory)) + ")\n");
|
||||
System.out.println(sb.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import org.eclipse.core.runtime.URIUtil;
|
||||
*/
|
||||
public class ResourceUtil {
|
||||
|
||||
private static final String BUNDLERESOURCE = "bundleresource"; //$NON-NLS-1$
|
||||
private static final String BUNDLERESOURCE = "bundleresource";
|
||||
|
||||
public static File convertResourceToFile(URL resource) throws IOException, URISyntaxException {
|
||||
File fileDir = null;
|
||||
@@ -40,24 +40,4 @@ public class ResourceUtil {
|
||||
return fileDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "getFileFromResource" returns a File from the given path relative to the class. When the path starts with
|
||||
* "/", the file can be located in a plugin (in the classpath of the plugin). This method must be used in plugin
|
||||
* mode. It will return null when it's called as a java application.
|
||||
*
|
||||
* @param clazz a class in the same plugin as the file to find
|
||||
* @param path the path of the file.
|
||||
* @return the file when found. Can return null. Otherwise will throw an exception
|
||||
* @throws IOException
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
public static File getFileFromResource(Class<?> clazz, String path) throws IOException, URISyntaxException {
|
||||
URL url = clazz.getResource(path);
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
URL fileURL = FileLocator.toFileURL(url);
|
||||
URI escapedUri = new URI(fileURL.getProtocol(), fileURL.getPath(), fileURL.getQuery());
|
||||
return new File(escapedUri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,49 +57,37 @@ public class EclipseCommandLine {
|
||||
*/
|
||||
static public final String TALEND_DISABLE_LOGINDIALOG_COMMAND = "--disableLoginDialog"; //$NON-NLS-1$
|
||||
|
||||
static public void updateOrCreateExitDataPropertyWithCommand(String command, String value, boolean delete) {
|
||||
updateOrCreateExitDataPropertyWithCommand(command, value, delete, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* this creates or updates the org.eclipse.equinox.app.IApplicationContext.EXIT_DATA_PROPERTY by adding or changing
|
||||
* the command with value, except if value is null then the command shall be removed.
|
||||
*
|
||||
* @param command the command to add or update or remove (if value is null) (usually starts with a -)
|
||||
* @param value the value of the command,if the value is null,will only update the commmanden
|
||||
* @param value the value of the command,if the value is null,will only update the commmand
|
||||
* @param delete the flag used to trigger delete or insert/update the command
|
||||
*/
|
||||
static public void updateOrCreateExitDataPropertyWithCommand(String command, String value, boolean delete, boolean isOption) {
|
||||
static public void updateOrCreateExitDataPropertyWithCommand(String command, String value, boolean delete) {
|
||||
boolean isValueNull = false;
|
||||
if (value == null || "".equals(value)) {
|
||||
isValueNull = true;
|
||||
}
|
||||
StringBuffer result = new StringBuffer(512);
|
||||
String patternStr = "\\s+.+\\s"; //$NON-NLS-1$
|
||||
// if the command is only one option. should only process the command without arguments.
|
||||
if (isOption) {
|
||||
patternStr = "\\s+"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
String currentProperty = System.getProperty(org.eclipse.equinox.app.IApplicationContext.EXIT_DATA_PROPERTY);
|
||||
if (currentProperty != null) {// update the property
|
||||
Pattern commandPattern = Pattern.compile(command + patternStr);// -talendRestart\s+.+\s
|
||||
Pattern commandPattern = Pattern.compile(command + "\\s+.+\\s");//$NON-NLS-1$ -talendRestart\s+.+\s
|
||||
Matcher restartMatcher = commandPattern.matcher(currentProperty);
|
||||
|
||||
if (delete) {// if delete,no matter the value is null or not,remove the command directly
|
||||
if (restartMatcher.find()) {// match found so remove it
|
||||
currentProperty = restartMatcher.replaceAll("");//$NON-NLS-1$
|
||||
currentProperty = restartMatcher.replaceAll("");
|
||||
} // else no match so do nothing
|
||||
} else {// else add or update the command
|
||||
// try to find existing commands to update them
|
||||
// find the index of the arg to replace its value
|
||||
// if value is null,only add or update the command
|
||||
if (restartMatcher.find()) {// match found so update the command
|
||||
if (isOption) {
|
||||
// because no arguments, if have been existed, so ignore.
|
||||
} else {
|
||||
currentProperty = restartMatcher.replaceAll(command + EclipseCommandLine.NEW_LINE
|
||||
+ (isValueNull ? "" : value + EclipseCommandLine.NEW_LINE));//$NON-NLS-1$
|
||||
}
|
||||
currentProperty = restartMatcher.replaceAll(command + EclipseCommandLine.NEW_LINE
|
||||
+ (isValueNull ? "" : value + EclipseCommandLine.NEW_LINE));//$NON-NLS-N$
|
||||
} else {// no match so insert it before the CMD_VMARGS
|
||||
int indexOfVmArgs = currentProperty.indexOf(CMD_VMARGS);
|
||||
if (indexOfVmArgs >= 0) {// found it so insert command before
|
||||
@@ -136,12 +124,12 @@ public class EclipseCommandLine {
|
||||
result.append(command);
|
||||
result.append(EclipseCommandLine.NEW_LINE);
|
||||
if (!isValueNull) {
|
||||
result.append(value);
|
||||
result.append(value); //$NON-NLS-1$
|
||||
result.append(EclipseCommandLine.NEW_LINE);
|
||||
}
|
||||
}// else command shall be removed,but it does not exists so ignor it
|
||||
} else {
|
||||
Pattern commandPattern = Pattern.compile(command + patternStr);// -talendRestart\s+.+\s
|
||||
Pattern commandPattern = Pattern.compile(command + "\\s+.+\\s");//$NON-NLS-1$ -talendRestart\s+.+\s
|
||||
Matcher restartMatcher = commandPattern.matcher(property);
|
||||
|
||||
if (delete) {// if delete,no matter the value is null or not,remove the command dirctly
|
||||
@@ -150,12 +138,8 @@ public class EclipseCommandLine {
|
||||
}
|
||||
} else {// else need add or update the
|
||||
if (restartMatcher.find()) {// match found so update the command
|
||||
if (isOption) {
|
||||
// because no arguments, if have been existed, so ignore.
|
||||
} else {
|
||||
property = restartMatcher.replaceAll(command + EclipseCommandLine.NEW_LINE
|
||||
+ (isValueNull ? "" : value + EclipseCommandLine.NEW_LINE));
|
||||
}
|
||||
property = restartMatcher.replaceAll(command + EclipseCommandLine.NEW_LINE
|
||||
+ (isValueNull ? "" : value + EclipseCommandLine.NEW_LINE));
|
||||
} else {// no match so add it
|
||||
result.append(command);
|
||||
result.append(EclipseCommandLine.NEW_LINE);
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.talend.commons.utils.data.map.MultiLazyValuesMap;
|
||||
/**
|
||||
* DOC amaumont class global comment. Detailled comment <br/>
|
||||
*
|
||||
* @deprecated use {@link}
|
||||
* @param <B> bean which contains the property id
|
||||
* @param <KP> type of the key/property
|
||||
*/
|
||||
@@ -129,7 +128,7 @@ public class Locker<B, KP> {
|
||||
|
||||
public String toString() {
|
||||
return StringUtils.replacePrms(
|
||||
"InternalKeyLock: thread={0}, key={1}, contextInfo={2}", Thread.currentThread().getName(), key, contextInfo); //$NON-NLS-1$
|
||||
"InternalKeyLock: key={0}, contextInfo={1}", Thread.currentThread().getName(), key, contextInfo); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,12 +203,10 @@ public class Locker<B, KP> {
|
||||
|
||||
private IGetterPropertyAccessor<B, KP> getterId;
|
||||
|
||||
private boolean allowReentrantLockFromLockerThread = true;
|
||||
private boolean allowLockWithSameThread = true;
|
||||
|
||||
/**
|
||||
* DOC amaumont Locker constructor comment.
|
||||
*
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey}
|
||||
*/
|
||||
public Locker() {
|
||||
super();
|
||||
@@ -217,20 +214,17 @@ public class Locker<B, KP> {
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor Locker.
|
||||
* DOC amaumont Locker constructor comment.
|
||||
*
|
||||
* @param allowReentrantLockFromLockerThread default is true
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey}
|
||||
* @param allowLockWithSameThread default is true
|
||||
*/
|
||||
public Locker(boolean allowReentrantLockFromLockerThread) {
|
||||
public Locker(boolean allowLockWithSameThread) {
|
||||
super();
|
||||
this.allowReentrantLockFromLockerThread = allowReentrantLockFromLockerThread;
|
||||
this.allowLockWithSameThread = allowLockWithSameThread;
|
||||
}
|
||||
|
||||
/**
|
||||
* DOC amaumont Locker constructor comment.
|
||||
*
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey}
|
||||
*/
|
||||
public Locker(IGetterPropertyAccessor<B, KP> getterId) {
|
||||
this();
|
||||
@@ -245,26 +239,17 @@ public class Locker<B, KP> {
|
||||
* DOC amaumont Locker constructor comment.
|
||||
*
|
||||
* @param getterId
|
||||
* @param allowReentrantLockFromLockerThread default is true
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey}
|
||||
* @param allowLockWithSameThread default is true
|
||||
*/
|
||||
public Locker(boolean allowReentrantLock, IGetterPropertyAccessor<B, KP> getterId) {
|
||||
public Locker(boolean allowLockWithSameThread, IGetterPropertyAccessor<B, KP> getterId) {
|
||||
this();
|
||||
this.getterId = getterId;
|
||||
if (getterId == null) {
|
||||
throw new IllegalArgumentException("getterId can't be null"); //$NON-NLS-1$
|
||||
}
|
||||
this.allowReentrantLockFromLockerThread = allowReentrantLock;
|
||||
this.allowLockWithSameThread = allowLockWithSameThread;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* DOC amaumont Comment method "isLockedBean".
|
||||
*
|
||||
* @param bean
|
||||
* @return
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#isLocked(Object)}
|
||||
*/
|
||||
public synchronized boolean isLockedBean(B bean) {
|
||||
checkBean(bean);
|
||||
KP key = getterId.get(bean);
|
||||
@@ -276,7 +261,6 @@ public class Locker<B, KP> {
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#isLocked(Object)}
|
||||
*/
|
||||
public synchronized boolean isLocked(KP key) {
|
||||
check(key);
|
||||
@@ -295,8 +279,6 @@ public class Locker<B, KP> {
|
||||
* @param bean
|
||||
* @return previous lock state, true was locked
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead replaced by
|
||||
* {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#lockInterruptibly(Object)}
|
||||
*/
|
||||
public synchronized boolean lockBean(B bean) {
|
||||
return lockBean(bean, UNDEFINED_CONTEXT_INFO);
|
||||
@@ -308,8 +290,6 @@ public class Locker<B, KP> {
|
||||
* @param bean
|
||||
* @return previous lock state, true was locked
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead replaced by
|
||||
* {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#lockInterruptibly(Object)}
|
||||
*/
|
||||
public synchronized boolean lockBean(B bean, String contextInfo) {
|
||||
checkBean(bean);
|
||||
@@ -318,27 +298,20 @@ public class Locker<B, KP> {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "lock". Lock the operations on the provided <code>key</code>.
|
||||
* DOC amaumont Comment method "lock".
|
||||
*
|
||||
* @param key
|
||||
* @return true if already locked, false if the lock is a new one
|
||||
* @deprecated use instead replaced by
|
||||
* {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#lockInterruptibly(Object)}
|
||||
* @return
|
||||
*/
|
||||
public boolean lock(KP key) {
|
||||
return lock(key, UNDEFINED_CONTEXT_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "lock". Lock the operations on the provided <code>key</code>.
|
||||
* DOC amaumont Comment method "lock".
|
||||
*
|
||||
* @param key
|
||||
* @param contextInfo
|
||||
* @return true if already locked, false if the lock is a new one
|
||||
* @deprecated use instead replaced by
|
||||
* {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#lockInterruptibly(Object)}
|
||||
* @return
|
||||
*/
|
||||
public boolean lock(KP key, String contextInfo) {
|
||||
check(key);
|
||||
@@ -361,7 +334,6 @@ public class Locker<B, KP> {
|
||||
* @param bean
|
||||
* @return true if lock has been done or current thread has already locked the same bean, else false.
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#tryLock(Object)}
|
||||
*/
|
||||
public synchronized boolean lockIfUnlockedBean(B bean) {
|
||||
return lockIfUnlockedBean(bean, UNDEFINED_CONTEXT_INFO);
|
||||
@@ -373,7 +345,6 @@ public class Locker<B, KP> {
|
||||
* @param bean
|
||||
* @return true if lock has been done or current thread has already locked the same bean, else false.
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#tryLock(Object)}
|
||||
*/
|
||||
public synchronized boolean lockIfUnlockedBean(B bean, String contextInfo) {
|
||||
checkBean(bean);
|
||||
@@ -384,7 +355,7 @@ public class Locker<B, KP> {
|
||||
KP key = getterId.get(bean);
|
||||
matchingKey.key = key;
|
||||
LockerValue valueLock = lockKeyToThreadsMap.get(matchingKey);
|
||||
if (allowReentrantLockFromLockerThread && valueLock != null && Thread.currentThread() == valueLock.thread) {
|
||||
if (allowLockWithSameThread && valueLock != null && Thread.currentThread() == valueLock.thread) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -398,7 +369,6 @@ public class Locker<B, KP> {
|
||||
* @param bean
|
||||
* @return true if lock has been done or current thread has already locked the same bean, else false.
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#tryLock(Object)}
|
||||
*/
|
||||
public synchronized boolean lockIfUnlocked(KP key) {
|
||||
return lockIfUnlocked(key, UNDEFINED_CONTEXT_INFO);
|
||||
@@ -410,7 +380,6 @@ public class Locker<B, KP> {
|
||||
* @param bean
|
||||
* @return true if lock has been done or current thread has already locked the same bean, else false.
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#tryLock(Object)}
|
||||
*/
|
||||
public synchronized boolean lockIfUnlocked(KP key, String contextInfo) {
|
||||
check(key);
|
||||
@@ -420,7 +389,7 @@ public class Locker<B, KP> {
|
||||
} else {
|
||||
matchingKey.key = key;
|
||||
LockerValue valueLock = lockKeyToThreadsMap.get(matchingKey);
|
||||
if (allowReentrantLockFromLockerThread && valueLock != null && Thread.currentThread() == valueLock.thread) {
|
||||
if (allowLockWithSameThread && valueLock != null && Thread.currentThread() == valueLock.thread) {
|
||||
// System.out.println("Same thread");
|
||||
return true;
|
||||
} else {
|
||||
@@ -452,24 +421,22 @@ public class Locker<B, KP> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "unlock". Unlock the operations with the provided key.
|
||||
* Unlock.
|
||||
*
|
||||
* @param bean
|
||||
* @return true if the key has unlocked, false if the key unlocked nothing
|
||||
* @return true unlock has been done, else false if no lock was exist
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#unlock(Object)}
|
||||
*/
|
||||
public boolean unlockBean(B bean) {
|
||||
return unlockBean(bean, UNDEFINED_CONTEXT_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "unlock". Unlock the operations with the provided key.
|
||||
* Unlock.
|
||||
*
|
||||
* @param bean
|
||||
* @return true if the key has unlocked, false if the key unlocked nothing
|
||||
* @return true unlock has been done, else false if no lock was exist
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#unlock(Object)}
|
||||
*/
|
||||
public synchronized boolean unlockBean(B bean, String contextInfo) {
|
||||
if (bean == null) {
|
||||
@@ -481,22 +448,20 @@ public class Locker<B, KP> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "unlock". Unlock the operations with the provided key.
|
||||
* DOC amaumont Comment method "unlock".
|
||||
*
|
||||
* @param key
|
||||
* @return true if the key has unlocked, false if the key unlocked nothing
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#unlock(Object)}
|
||||
* @return
|
||||
*/
|
||||
public boolean unlock(KP key) {
|
||||
return unlock(key, UNDEFINED_CONTEXT_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "unlock". Unlock the operations with the provided key.
|
||||
* DOC amaumont Comment method "unlock".
|
||||
*
|
||||
* @param key
|
||||
* @return true if the key has unlocked, false if the key unlocked nothing
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#unlock(Object)}
|
||||
* @return
|
||||
*/
|
||||
public synchronized boolean unlock(KP key, String contextInfo) {
|
||||
check(key);
|
||||
@@ -520,30 +485,22 @@ public class Locker<B, KP> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "waitForLockBean". Lock now if possible with the provided key, else wait for unlocked to lock.
|
||||
* DOC amaumont Comment method "waitForLockBean".
|
||||
*
|
||||
* @param bean
|
||||
* @return true if the current thread has wait a time before able to lock, else false.
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#lockInterruptibly(KP)}
|
||||
* @param executionTask
|
||||
* @param idLockForceInitCheck
|
||||
*/
|
||||
public boolean waitForLockBean(B bean) throws InterruptedException {
|
||||
return waitForLockBean(bean, UNDEFINED_CONTEXT_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "waitForLockBean". Lock now if possible with the provided key, else wait for unlocked to lock.
|
||||
*
|
||||
* It allows by default reentrant locks from the first locker thread. If you don't want reentrant lock, you have to
|
||||
* set <code>allowReentrantLockFromLockerThread</code> = <code>false</code> from the <code>Locker</code>
|
||||
* constructor.
|
||||
* Lock if it is unlocked, else waiting for unlocked to lock.
|
||||
*
|
||||
* @param bean
|
||||
* @return true if the current thread has wait a time before able to lock, else false.
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#lockInterruptibly(KP)}
|
||||
*/
|
||||
public boolean waitForLockBean(B bean, String contextInfo) throws InterruptedException {
|
||||
checkBean(bean);
|
||||
@@ -576,52 +533,37 @@ public class Locker<B, KP> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "waitForLock". Lock now if possible with the provided key, else wait for unlocked to lock.
|
||||
*
|
||||
* It allows by default reentrant locks from the first locker thread. If you don't want reentrant lock, you have to
|
||||
* set <code>allowReentrantLockFromLockerThread</code> = <code>false</code> from the <code>Locker</code>
|
||||
* constructor.
|
||||
* Lock if it is unlocked, else waiting for unlocked to lock.
|
||||
*
|
||||
* @param bean
|
||||
* @return true if thread has wait a time, else false.
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#lockInterruptibly(KP)}
|
||||
*/
|
||||
public boolean waitForLock(KP key) throws InterruptedException {
|
||||
return waitForLock(key, UNDEFINED_CONTEXT_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "waitForLock". Lock now if possible with the provided key, else wait for unlocked to lock.
|
||||
*
|
||||
* It allows by default reentrant locks from the first locker thread. If you don't want reentrant lock, you have to
|
||||
* set <code>allowReentrantLockFromLockerThread</code> = <code>false</code> from the <code>Locker</code>
|
||||
* constructor.
|
||||
* Lock if it is unlocked, else waiting for unlocked to lock.
|
||||
*
|
||||
* @param key
|
||||
* @param waitTimeMax the maximum time to wait in milliseconds.
|
||||
* @return true if thread has wait a time, else false.
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#tryLock(Object, long)}
|
||||
*/
|
||||
public boolean waitForLock(KP key, Long waitTimeMax) throws InterruptedException {
|
||||
return waitForLock(key, waitTimeMax, UNDEFINED_CONTEXT_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "waitForLock". Lock now if possible with the provided key, else wait for unlocked to lock.
|
||||
* Lock if it is unlocked, else waiting for unlocked to lock.
|
||||
*
|
||||
* It allows by default reentrant locks from the first locker thread. If you don't want reentrant lock, you have to
|
||||
* set <code>allowReentrantLockFromLockerThread</code> = <code>false</code> from the <code>Locker</code>
|
||||
* constructor.
|
||||
*
|
||||
* @param key
|
||||
* @param bean
|
||||
* @return true if thread has wait a time, else false.
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#lockInterruptibly(KP)}
|
||||
*/
|
||||
public boolean waitForLock(KP key, String contextInfo) throws InterruptedException {
|
||||
return waitForLock(key, null, contextInfo);
|
||||
@@ -632,7 +574,6 @@ public class Locker<B, KP> {
|
||||
*
|
||||
* @param bean
|
||||
* @return locker value.
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#getLockerValue(Object)}
|
||||
*/
|
||||
public LockerValue getLocker(KP key) {
|
||||
check(key);
|
||||
@@ -642,20 +583,13 @@ public class Locker<B, KP> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "waitForLock". Lock now if possible with the provided key, else wait for unlocked to lock.
|
||||
*
|
||||
* It allows by default reentrant locks from the first locker thread. If you don't want reentrant lock, you have to
|
||||
* set <code>allowReentrantLockFromLockerThread</code> = <code>false</code> from the <code>Locker</code>
|
||||
* constructor.
|
||||
* Lock if it is unlocked, else waiting for unlocked to lock.
|
||||
*
|
||||
* @param key
|
||||
* @param waitTimeMax the maximum time to wait in milliseconds.
|
||||
* @return true if thread has wait a time, else false.
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#lockInterruptibly(KP)} or
|
||||
* {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey#tryLock(Object, long)} according the case (without or with
|
||||
* timeout)
|
||||
*/
|
||||
public boolean waitForLock(KP key, final Long waitTimeMax, String contextInfo) throws InterruptedException {
|
||||
check(key);
|
||||
@@ -739,10 +673,6 @@ public class Locker<B, KP> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated use instead {@link org.talend.commons.utils.threading.lockerbykey.LockerByKey}
|
||||
*/
|
||||
public synchronized void shutdown() {
|
||||
Object[] values = waitingThreadsByKey.values().toArray(new Object[0]);
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
@@ -766,6 +696,17 @@ public class Locker<B, KP> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* DOC amaumont Comment method "setVerbose".
|
||||
*
|
||||
* @param verbose
|
||||
*
|
||||
* @deprecated enable logs with TRACE level for this class instead use this method
|
||||
*/
|
||||
public static void setVerbose(boolean verbose) {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Locker";
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package org.talend.commons.utils.threading.lockerbykey;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
*
|
||||
* CustomReentrantLock class.
|
||||
*
|
||||
* @see java.util.concurrent.locks.ReentrantLock
|
||||
*/
|
||||
public class CustomReentrantLock extends ReentrantLock {
|
||||
|
||||
private static final long serialVersionUID = 3730576759454516775L;
|
||||
|
||||
public CustomReentrantLock() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CustomReentrantLock(boolean fair) {
|
||||
super(fair);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.concurrent.locks.ReentrantLock#getQueuedThreads()
|
||||
*/
|
||||
@Override
|
||||
public Collection<Thread> getQueuedThreads() {
|
||||
return super.getQueuedThreads();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.locks.ReentrantLock#getOwner()
|
||||
*/
|
||||
@Override
|
||||
public Thread getOwner() {
|
||||
return super.getOwner();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
package org.talend.commons.utils.threading.lockerbykey;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* DOC amaumont class global comment. Detailled comment
|
||||
*/
|
||||
public interface ILockerByKey<KP> {
|
||||
|
||||
public abstract int getCleanPeriod();
|
||||
|
||||
public abstract void shutdown();
|
||||
|
||||
public abstract LockerValue<KP> getLockerValue(KP key);
|
||||
|
||||
public abstract boolean unlock(KP key);
|
||||
|
||||
public abstract boolean tryLock(KP key, long timeout, TimeUnit unit) throws InterruptedException;
|
||||
|
||||
public abstract boolean tryLock(KP key, long timeout) throws InterruptedException;
|
||||
|
||||
public abstract boolean tryLock(KP key);
|
||||
|
||||
public abstract void lockInterruptibly(KP key) throws InterruptedException;
|
||||
|
||||
public abstract boolean isLocked(KP key);
|
||||
|
||||
public abstract void clean();
|
||||
|
||||
public abstract List<LockerValue<KP>> getSuspectLocks(long timeDetectionLimitMs);
|
||||
|
||||
public abstract void setDetectSuspectLocks(boolean detectSuspectLocks);
|
||||
|
||||
public abstract boolean isDetectSuspectLocks();
|
||||
|
||||
}
|
||||
@@ -1,590 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.lockerbykey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.talend.commons.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* This class is useful to lock some part of code from the provided key.
|
||||
*
|
||||
* This class has the same behaviour that <code>java.util.concurrent.locks.ReentrantLock</code> except additionally it
|
||||
* expect keys to lock the parts of code.
|
||||
*
|
||||
* It uses internally a <code>java.util.concurrent.ConcurrentHashMap</code> to store locks from keys <code>KP</code> and
|
||||
* the <code>java.util.concurrent.locks.ReentrantLock</code> as properties of a value wrapper. <br/>
|
||||
*
|
||||
* @see java.util.concurrent.locks.ReentrantLock
|
||||
*
|
||||
* @param <KP> type of the key
|
||||
*/
|
||||
public class LockerByKey<KP> implements ILockerByKey<KP> {
|
||||
|
||||
private static Logger log = Logger.getLogger(LockerByKey.class);
|
||||
|
||||
ConcurrentHashMap<InternalKeyLock<KP>, LockerValue<KP>> mapKeyLockToValueLock = new ConcurrentHashMap<InternalKeyLock<KP>, LockerValue<KP>>();
|
||||
|
||||
private final Object lockAllOperations = new Object();
|
||||
|
||||
private AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
private AtomicInteger runningOperations = new AtomicInteger();
|
||||
|
||||
private final static int DEFAULT_CLEAN_PERIOD = 500;
|
||||
|
||||
private final static boolean DEFAULT_FAIR = true;
|
||||
|
||||
private int cleanPeriod;
|
||||
|
||||
private boolean fair;
|
||||
|
||||
private volatile boolean blockAllOperations;
|
||||
|
||||
private volatile boolean shuttingDown;
|
||||
|
||||
private volatile boolean stopped;
|
||||
|
||||
private static boolean detectSuspectLocksStatic = false;
|
||||
|
||||
private boolean detectSuspectLocks = false;
|
||||
|
||||
static {
|
||||
String optionKey = "detectSuspectLocks";
|
||||
String lockDeployOnSameAddressStr = System.getProperty(optionKey);
|
||||
if (lockDeployOnSameAddressStr != null && lockDeployOnSameAddressStr.length() > 0) {
|
||||
detectSuspectLocksStatic = Boolean.parseBoolean(lockDeployOnSameAddressStr);
|
||||
}
|
||||
if (detectSuspectLocksStatic) {
|
||||
log.info("System property \"" + optionKey + "\"=" + detectSuspectLocksStatic);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LockerByKey constructor.
|
||||
*/
|
||||
public LockerByKey() {
|
||||
this(DEFAULT_FAIR, DEFAULT_CLEAN_PERIOD);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor LockerByKey.
|
||||
*
|
||||
* @param fair {@code true} if this lock should use a fair ordering policy
|
||||
*/
|
||||
public LockerByKey(boolean fair) {
|
||||
this(fair, DEFAULT_CLEAN_PERIOD);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor LockerByKey.
|
||||
*
|
||||
* @param cleanPeriod in number of operations, it means that an automatic clean will be done for each
|
||||
* <code>cleanPeriod</code> number of unlock operation.
|
||||
*/
|
||||
public LockerByKey(int cleanPeriod) {
|
||||
this(DEFAULT_FAIR, cleanPeriod);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor LockerByKey.
|
||||
*
|
||||
* @param fair {@code true} if this lock should use a fair ordering policy
|
||||
* @param cleanPeriod in number of operations, it means that an automatic clean will be done after each
|
||||
* <code>cleanPeriod</code> number of unlock operation.
|
||||
*/
|
||||
public LockerByKey(boolean fair, int cleanPeriod) {
|
||||
super();
|
||||
this.fair = fair;
|
||||
if (cleanPeriod <= 0) {
|
||||
throw new IllegalArgumentException("The cleanPeriod value has to be greater than 0");
|
||||
}
|
||||
this.cleanPeriod = cleanPeriod;
|
||||
this.detectSuspectLocks = detectSuspectLocksStatic;
|
||||
if (this.detectSuspectLocks) {
|
||||
launchThreadDebugger();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor LockerByKey.
|
||||
*
|
||||
* @param fair {@code true} if this lock should use a fair ordering policy
|
||||
* @param cleanDisabled true to disable the clean completely <code>cleanPeriod</code> number of unlock operation.
|
||||
*/
|
||||
protected LockerByKey(boolean fair, boolean cleanDisabled) {
|
||||
super();
|
||||
this.fair = fair;
|
||||
if (cleanDisabled) {
|
||||
this.cleanPeriod = 0;
|
||||
} else {
|
||||
this.cleanPeriod = DEFAULT_CLEAN_PERIOD;
|
||||
}
|
||||
this.detectSuspectLocks = detectSuspectLocksStatic;
|
||||
if (this.detectSuspectLocks) {
|
||||
launchThreadDebugger();
|
||||
}
|
||||
}
|
||||
|
||||
private void launchThreadDebugger() {
|
||||
new Thread(this.getClass().getSimpleName() + "-ThreadDebugger-" + this.hashCode()) {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Thread#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
while (!stopped && !shuttingDown) {
|
||||
try {
|
||||
Thread.sleep(30000);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
long timeDetectionLimitMs = 30000L;
|
||||
List<LockerValue<KP>> lockerValues = getSuspectLocks(timeDetectionLimitMs);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (LockerValue<KP> lockerValue : lockerValues) {
|
||||
long duration = System.currentTimeMillis() - lockerValue.getLockedTime();
|
||||
StackTraceElement[] stackTraceOfLocker = lockerValue.getStackTraceOfLocker();
|
||||
for (StackTraceElement trace : stackTraceOfLocker) {
|
||||
StackTraceElement stackTraceElement = trace;
|
||||
sb.append(stackTraceElement.toString());
|
||||
sb.append("\n");
|
||||
}
|
||||
log.warn("Suspect lock done since " + duration + " ms by: " + sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "isLocked".
|
||||
*
|
||||
* @param key
|
||||
* @return true if any thread holds this lock and false otherwise
|
||||
*
|
||||
* @see java.util.concurrent.locks.ReentrantLock#isLocked()
|
||||
*/
|
||||
@Override
|
||||
public boolean isLocked(KP key) {
|
||||
checkKey(key);
|
||||
LockerValue<KP> locker = getLockerValue(key);
|
||||
return locker != null && locker.getLock().isLocked();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "lockInterruptibly".
|
||||
*
|
||||
* @param key
|
||||
* @throws InterruptedException
|
||||
* @see java.util.concurrent.locks.ReentrantLock#lockInterruptibly()
|
||||
*/
|
||||
@Override
|
||||
public void lockInterruptibly(KP key) throws InterruptedException {
|
||||
checkStopped();
|
||||
checkKey(key);
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
LockerValue<KP> lockerValue = prepareInternalLock(key);
|
||||
decrementRunningOperations();
|
||||
lockerValue.getLock().lockInterruptibly();
|
||||
traceStackForDebugging(lockerValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "tryLock".
|
||||
*
|
||||
* @param key
|
||||
* @return {@code true} if the lock was free and was acquired by the current thread, or the lock was already held by
|
||||
* the current thread; and {@code false} otherwise
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @see java.util.concurrent.locks.ReentrantLock#tryLock()
|
||||
*/
|
||||
@Override
|
||||
public boolean tryLock(KP key) {
|
||||
if (stopped || shuttingDown) {
|
||||
return false;
|
||||
}
|
||||
checkKey(key);
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
LockerValue<KP> lockerValue = prepareInternalLock(key);
|
||||
decrementRunningOperations();
|
||||
boolean locked = lockerValue.getLock().tryLock();
|
||||
if (locked) {
|
||||
traceStackForDebugging(lockerValue);
|
||||
}
|
||||
return locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "tryLock".
|
||||
*
|
||||
* @param key
|
||||
* @param timeout the time to wait for the lock in milliseconds
|
||||
* @return true if the lock was free and was acquired by the current thread, or the lock was already held by the
|
||||
* current thread; and false if the waiting time elapsed before the lock could be acquired
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @see java.util.concurrent.locks.ReentrantLock#tryLock(long, java.util.concurrent.TimeUnit)
|
||||
*/
|
||||
@Override
|
||||
public boolean tryLock(KP key, long timeout) throws InterruptedException {
|
||||
return tryLock(key, timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "tryLock".
|
||||
*
|
||||
* @param key
|
||||
* @param timeout the time to wait for the lock
|
||||
* @param unit the time unit of the timeout argument
|
||||
* @return true if the lock was free and was acquired by the current thread, or the lock was already held by the
|
||||
* current thread; and false if the waiting time elapsed before the lock could be acquired
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
*
|
||||
* @see java.util.concurrent.locks.ReentrantLock#tryLock(long, java.util.concurrent.TimeUnit)
|
||||
*/
|
||||
@Override
|
||||
public boolean tryLock(KP key, long timeout, TimeUnit unit) throws InterruptedException {
|
||||
checkStopped();
|
||||
checkKey(key);
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
LockerValue<KP> lockerValue = prepareInternalLock(key);
|
||||
decrementRunningOperations();
|
||||
interruptIfStopping();
|
||||
boolean locked = lockerValue.getLock().tryLock(timeout, unit);
|
||||
if (locked) {
|
||||
traceStackForDebugging(lockerValue);
|
||||
}
|
||||
return locked;
|
||||
}
|
||||
|
||||
private LockerValue<KP> prepareInternalLock(KP key) {
|
||||
InternalKeyLock<KP> internalKeyLock = new InternalKeyLock<KP>(key);
|
||||
LockerValue<KP> lockerValue = new LockerValue<KP>(key, fair);
|
||||
LockerValue<KP> previousLockerValue = null;
|
||||
previousLockerValue = mapKeyLockToValueLock.putIfAbsent(internalKeyLock, lockerValue);
|
||||
if (previousLockerValue != null) {
|
||||
lockerValue = previousLockerValue;
|
||||
}
|
||||
return lockerValue;
|
||||
}
|
||||
|
||||
private void interruptIfStopping() throws InterruptedException {
|
||||
if (shuttingDown) {
|
||||
throw new InterruptedException("This LockerByKey is shutting down...");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "unlock". Unlock the operations with the provided key.
|
||||
*
|
||||
* @param key
|
||||
* @return true if the key has been found to release the lock; and false otherwise
|
||||
* @see java.util.concurrent.locks.ReentrantLock#unlock()
|
||||
*/
|
||||
@Override
|
||||
public boolean unlock(KP key) {
|
||||
checkKey(key);
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
LockerValue<KP> lockerValue = getLockerValue(key);
|
||||
boolean returnValue = false;
|
||||
if (lockerValue != null) {
|
||||
lockerValue.getLock().unlock();
|
||||
returnValue = true;
|
||||
}
|
||||
decrementRunningOperations();
|
||||
cleanAccordingOperations();
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void traceStackForDebugging(LockerValue<KP> lockerValue) {
|
||||
if (this.detectSuspectLocks) {
|
||||
lockerValue.setStackTraceOfLocker(Thread.currentThread().getStackTrace());
|
||||
lockerValue.setLockedTime(System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanAccordingOperations() {
|
||||
synchronized (lockAllOperations) {
|
||||
if (cleanPeriod > 0 && counter.incrementAndGet() % cleanPeriod == 0) {
|
||||
clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "clean".
|
||||
*
|
||||
* Clean the map which contains the lock wrappers.
|
||||
*
|
||||
* Removed lock wrappers are these where lock is not locked by a thread and no one thread is waiting to obtain the
|
||||
* lock.
|
||||
*
|
||||
* The default clean will do an automatic clean all 1000 unlock operation, you can disable or change this value from
|
||||
* the constructor.
|
||||
*/
|
||||
public void clean() {
|
||||
synchronized (lockAllOperations) {
|
||||
waitForRunningOperationsEnded();
|
||||
Collection<LockerValue<KP>> values = mapKeyLockToValueLock.values();
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Cleaning " + this.toString() + " : " + values.size() + " keys/values ...");
|
||||
}
|
||||
InternalKeyLock<KP> internalKeyLock = new InternalKeyLock<KP>();
|
||||
for (LockerValue<KP> lockerValue : values) {
|
||||
ReentrantLock lock = lockerValue.getLock();
|
||||
LockerValueHandler handler = lockerValue.getHandler();
|
||||
if (!lock.hasQueuedThreads() && !lock.isLocked() && handler == null) {
|
||||
internalKeyLock.setKey(lockerValue.getKey());
|
||||
mapKeyLockToValueLock.remove(internalKeyLock);
|
||||
}
|
||||
}
|
||||
resumeAllOperations();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkStopped() {
|
||||
if (stopped || shuttingDown) {
|
||||
throw new IllegalStateException("This locker is already stopped or is shutting down !");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "check". Check if the key is not null.
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
private void checkKey(KP key) {
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("key can't be null"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
private void waitForRunningOperationsEnded() {
|
||||
blockAllOperations();
|
||||
while (runningOperations.get() > 0) {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resumeAllOperations() {
|
||||
this.blockAllOperations = false;
|
||||
lockAllOperations.notifyAll();
|
||||
}
|
||||
|
||||
private void blockAllOperations() {
|
||||
this.blockAllOperations = true;
|
||||
}
|
||||
|
||||
private void blockOperationIfRequired() {
|
||||
if (blockAllOperations) {
|
||||
synchronized (lockAllOperations) {
|
||||
if (blockAllOperations) {
|
||||
try {
|
||||
lockAllOperations.wait();
|
||||
} catch (InterruptedException e) {
|
||||
log.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void decrementRunningOperations() {
|
||||
runningOperations.decrementAndGet();
|
||||
}
|
||||
|
||||
private void incrementRunningOperations() {
|
||||
runningOperations.incrementAndGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get locker.
|
||||
*
|
||||
* @param bean
|
||||
* @return locker value.
|
||||
*/
|
||||
@Override
|
||||
public LockerValue<KP> getLockerValue(KP key) {
|
||||
checkKey(key);
|
||||
InternalKeyLock<KP> internalKeyLock = new InternalKeyLock<KP>(key);
|
||||
return mapKeyLockToValueLock.get(internalKeyLock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void shutdown() {
|
||||
shuttingDown = true;
|
||||
waitForRunningOperationsEnded();
|
||||
Collection<LockerValue<KP>> values = mapKeyLockToValueLock.values();
|
||||
for (LockerValue<KP> lockerValue : values) {
|
||||
Collection<Thread> queuedThreads = lockerValue.getLock().getQueuedThreads();
|
||||
for (Thread thread : queuedThreads) {
|
||||
thread.interrupt();
|
||||
}
|
||||
}
|
||||
clean();
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "LockerByKey:" + super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for cleanFrequency.
|
||||
*
|
||||
* @return the cleanFrequency
|
||||
*/
|
||||
@Override
|
||||
public int getCleanPeriod() {
|
||||
return cleanPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for detectSuspectLocks.
|
||||
*
|
||||
* @return the detectSuspectLocks
|
||||
*/
|
||||
@Override
|
||||
public boolean isDetectSuspectLocks() {
|
||||
return this.detectSuspectLocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the detectSuspectLocks.
|
||||
*
|
||||
* @param detectSuspectLocks the detectSuspectLocks to set
|
||||
*/
|
||||
@Override
|
||||
public void setDetectSuspectLocks(boolean detectSuspectLocks) {
|
||||
this.detectSuspectLocks = detectSuspectLocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LockerValue<KP>> getSuspectLocks(long timeDetectionLimitMs) {
|
||||
if (this.detectSuspectLocks) {
|
||||
Collection<LockerValue<KP>> values = mapKeyLockToValueLock.values();
|
||||
List<LockerValue<KP>> stacks = new ArrayList<LockerValue<KP>>();
|
||||
for (LockerValue<KP> lockerValue : values) {
|
||||
long lockedTime = lockerValue.getLockedTime();
|
||||
long duration = System.currentTimeMillis() - lockedTime;
|
||||
if (lockedTime > 0 && duration > timeDetectionLimitMs && lockerValue.getLock().isLocked()) {
|
||||
stacks.add(lockerValue);
|
||||
}
|
||||
}
|
||||
return stacks;
|
||||
} else {
|
||||
throw new UnsupportedOperationException(
|
||||
"You have to enable the 'detectSuspectLocks' mode by using the JVM argument -DdetectSuspectLocks=true");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* LockerByKey class.<br/>
|
||||
*
|
||||
* @param <IKP> key
|
||||
*/
|
||||
class InternalKeyLock<IKP> {
|
||||
|
||||
private IKP key;
|
||||
|
||||
public InternalKeyLock() {
|
||||
}
|
||||
|
||||
/**
|
||||
* InternalKeyLock constructor comment.
|
||||
*
|
||||
* @param key2
|
||||
*/
|
||||
public InternalKeyLock(IKP key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.key == null) ? 0 : this.key.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final InternalKeyLock other = (InternalKeyLock) obj;
|
||||
if (this.key == null) {
|
||||
if (other.key != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!this.key.equals(other.key)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setKey(IKP key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return StringUtils.replacePrms(InternalKeyLock.class.getSimpleName() + ": key={0}", key); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,657 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.commons.utils.threading.lockerbykey;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class LockerByKeyUnrestricted.
|
||||
*
|
||||
* This class has the same behaviours that {@link LockerByKey} except
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class LockerByKeyUnrestricted<KP> implements ILockerByKey<KP> {
|
||||
|
||||
private static final String NOT_ALREADY_LOCKED_MESSAGE = "Already unlocked by an other thread or never locked, ensure all the unlock() operations of this locker are called after their lock has really locked:";
|
||||
|
||||
private static Logger log = Logger.getLogger(LockerByKeyUnrestricted.class);
|
||||
|
||||
private ExecutorService threadPool;
|
||||
|
||||
private LockerByKey<KP> locker;
|
||||
|
||||
private final Object lockAllOperations = new Object();
|
||||
|
||||
private AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
private AtomicInteger runningOperations = new AtomicInteger();
|
||||
|
||||
private final static int DEFAULT_CLEAN_PERIOD = 500;
|
||||
|
||||
private final static boolean DEFAULT_FAIR = true;
|
||||
|
||||
private volatile boolean blockAllOperations;
|
||||
|
||||
private volatile boolean shuttingDown;
|
||||
|
||||
private volatile boolean stopped;
|
||||
|
||||
private int cleanPeriod;
|
||||
|
||||
/**
|
||||
* LockerByKey constructor.
|
||||
*/
|
||||
public LockerByKeyUnrestricted() {
|
||||
this(DEFAULT_FAIR, DEFAULT_CLEAN_PERIOD);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor LockerByKey.
|
||||
*
|
||||
* @param fair {@code true} if this lock should use a fair ordering policy
|
||||
*/
|
||||
public LockerByKeyUnrestricted(boolean fair) {
|
||||
this(fair, DEFAULT_CLEAN_PERIOD);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor LockerByKey.
|
||||
*
|
||||
* @param cleanPeriod in number of operations, it means that an automatic clean will be done for each
|
||||
* <code>cleanPeriod</code> number of unlock operation.
|
||||
*/
|
||||
public LockerByKeyUnrestricted(int cleanPeriod) {
|
||||
this(DEFAULT_FAIR, cleanPeriod);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Constructor LockerByKey.
|
||||
*
|
||||
* @param fair {@code true} if this lock should use a fair ordering policy
|
||||
* @param cleanPeriod in number of operations, it means that an automatic clean will be done for each
|
||||
* <code>cleanPeriod</code> number of unlock operation.
|
||||
*/
|
||||
public LockerByKeyUnrestricted(boolean fair, int cleanPeriod) {
|
||||
super();
|
||||
if (cleanPeriod <= 0) {
|
||||
throw new IllegalArgumentException("The cleanPeriod value has to be greater than 0");
|
||||
}
|
||||
boolean cleanDisabled = true;
|
||||
this.locker = new LockerByKey<KP>(fair, cleanDisabled);
|
||||
this.threadPool = intializePool(LockerByKeyUnrestricted.class.getSimpleName());
|
||||
this.cleanPeriod = cleanPeriod;
|
||||
}
|
||||
|
||||
protected ExecutorService intializePool(final String poolName) {
|
||||
ExecutorService threadPool = Executors.newCachedThreadPool(new ThreadFactory() {
|
||||
|
||||
ThreadFactory defaultThreadFactory = Executors.defaultThreadFactory();
|
||||
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread newThread = defaultThreadFactory.newThread(r);
|
||||
newThread.setName(poolName + "_" + newThread.getName());
|
||||
return newThread;
|
||||
}
|
||||
|
||||
});
|
||||
return threadPool;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "lockInterruptibly".
|
||||
*
|
||||
* @param key
|
||||
* @throws InterruptedException
|
||||
* @see java.util.concurrent.locks.ReentrantLock#lockInterruptibly()
|
||||
*/
|
||||
@Override
|
||||
public void lockInterruptibly(final KP key) throws InterruptedException {
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
try {
|
||||
locker.lockInterruptibly(key);
|
||||
} finally {
|
||||
decrementRunningOperations();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "lockInterruptiblyUnrestricted".
|
||||
*
|
||||
* @param key
|
||||
* @throws InterruptedException
|
||||
* @see java.util.concurrent.locks.ReentrantLock#lockInterruptibly()
|
||||
*/
|
||||
public void lockInterruptiblyUnrestricted(final KP key) throws InterruptedException {
|
||||
checkStopped();
|
||||
blockOperationIfRequired();
|
||||
|
||||
LockerValue<KP> lockerValue = null;
|
||||
LockerValueHandler handler = null;
|
||||
|
||||
if (tryLockUnrestricted(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
incrementRunningOperations();
|
||||
|
||||
/* Test if already locked by the same thread */
|
||||
lockerValue = locker.getLockerValue(key);
|
||||
if (locker != null) {
|
||||
handler = lockerValue.getHandler();
|
||||
if (handler != null && Thread.currentThread() == handler.getCallerThreadLocker()) {
|
||||
decrementRunningOperations();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final Thread threadLocker = Thread.currentThread();
|
||||
final CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
|
||||
final AtomicBoolean hasError = new AtomicBoolean();
|
||||
Callable<Boolean> callable = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
try {
|
||||
locker.lockInterruptibly(key);
|
||||
} catch (Exception e) {
|
||||
hasError.set(true);
|
||||
throw e;
|
||||
} finally {
|
||||
// STEP 1
|
||||
cyclicBarrier.await();
|
||||
}
|
||||
// STEP 2
|
||||
cyclicBarrier.await();
|
||||
boolean unlocked = locker.unlock(key);
|
||||
return unlocked;
|
||||
}
|
||||
|
||||
};
|
||||
Future<Boolean> futureTask = threadPool.submit(callable);
|
||||
try {
|
||||
// STEP 1
|
||||
cyclicBarrier.await();
|
||||
} catch (BrokenBarrierException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (hasError.get()) {
|
||||
try {
|
||||
futureTask.get();
|
||||
} catch (ExecutionException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause != null && cause instanceof InterruptedException) {
|
||||
throw (InterruptedException) cause;
|
||||
} else {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lockerValue = locker.getLockerValue(key);
|
||||
lockerValue.addHandler(new LockerValueHandler(futureTask, cyclicBarrier, threadLocker));
|
||||
} finally {
|
||||
decrementRunningOperations();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "tryLock".
|
||||
*
|
||||
* @param key
|
||||
* @return {@code true} if the lock was free and was acquired by the current thread, or the lock was already held by
|
||||
* the current thread; and {@code false} otherwise
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @see java.util.concurrent.locks.ReentrantLock#tryLock()
|
||||
*/
|
||||
@Override
|
||||
public boolean tryLock(final KP key) {
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
try {
|
||||
return locker.tryLock(key);
|
||||
} finally {
|
||||
decrementRunningOperations();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "tryLockUnrestricted".
|
||||
*
|
||||
* @param key
|
||||
* @return {@code true} if the lock was free and was acquired by the current thread, or the lock was already held by
|
||||
* the current thread; and {@code false} otherwise
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @see java.util.concurrent.locks.ReentrantLock#tryLock()
|
||||
*/
|
||||
public boolean tryLockUnrestricted(final KP key) {
|
||||
checkStopped();
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
boolean tryLockResultBoolean;
|
||||
try {
|
||||
final AtomicBoolean tryLockResult = new AtomicBoolean();
|
||||
final CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
|
||||
Callable<Boolean> callable = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
boolean locked;
|
||||
try {
|
||||
locked = locker.tryLock(key);
|
||||
tryLockResult.set(locked);
|
||||
} finally {
|
||||
// STEP 1
|
||||
cyclicBarrier.await();
|
||||
}
|
||||
if (locked) {
|
||||
// STEP 2
|
||||
cyclicBarrier.await();
|
||||
return locker.unlock(key);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
Future<Boolean> futureTask = threadPool.submit(callable);
|
||||
try {
|
||||
// STEP 1
|
||||
cyclicBarrier.await();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
tryLockResultBoolean = tryLockResult.get();
|
||||
if (tryLockResultBoolean) {
|
||||
LockerValue<KP> lockerValue = locker.getLockerValue(key);
|
||||
Thread callerThreadLocker = Thread.currentThread();
|
||||
lockerValue.addHandler(new LockerValueHandler(futureTask, cyclicBarrier, callerThreadLocker));
|
||||
}
|
||||
} finally {
|
||||
decrementRunningOperations();
|
||||
}
|
||||
return tryLockResultBoolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "tryLock".
|
||||
*
|
||||
* @param key
|
||||
* @param timeout the time to wait for the lock in milliseconds
|
||||
* @return true if the lock was free and was acquired by the current thread, or the lock was already held by the
|
||||
* current thread; and false if the waiting time elapsed before the lock could be acquired
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @see java.util.concurrent.locks.ReentrantLock#tryLock(long, java.util.concurrent.TimeUnit)
|
||||
*/
|
||||
@Override
|
||||
public boolean tryLock(final KP key, final long timeout) throws InterruptedException {
|
||||
return locker.tryLock(key, timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "tryLockUnrestricted".
|
||||
*
|
||||
* @param key
|
||||
* @param timeout the time to wait for the lock in milliseconds
|
||||
* @return true if the lock was free and was acquired by the current thread, or the lock was already held by the
|
||||
* current thread; and false if the waiting time elapsed before the lock could be acquired
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
* @see java.util.concurrent.locks.ReentrantLock#tryLock(long, java.util.concurrent.TimeUnit)
|
||||
*/
|
||||
public boolean tryLockUnrestricted(final KP key, final long timeout) throws InterruptedException {
|
||||
return tryLockUnrestricted(key, timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "tryLock".
|
||||
*
|
||||
* @param key
|
||||
* @param timeout the time to wait for the lock
|
||||
* @param unit the time unit of the timeout argument
|
||||
* @return true if the lock was free and was acquired by the current thread, or the lock was already held by the
|
||||
* current thread; and false if the waiting time elapsed before the lock could be acquired
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
*
|
||||
* @see java.util.concurrent.locks.ReentrantLock#tryLock(long, java.util.concurrent.TimeUnit)
|
||||
*/
|
||||
@Override
|
||||
public boolean tryLock(final KP key, final long timeout, final TimeUnit unit) throws InterruptedException {
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
try {
|
||||
return locker.tryLock(key, timeout, unit);
|
||||
} finally {
|
||||
decrementRunningOperations();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "tryLockUnrestricted".
|
||||
*
|
||||
* @param key
|
||||
* @param timeout the time to wait for the lock
|
||||
* @param unit the time unit of the timeout argument
|
||||
* @return true if the lock was free and was acquired by the current thread, or the lock was already held by the
|
||||
* current thread; and false if the waiting time elapsed before the lock could be acquired
|
||||
* @throws InterruptedException
|
||||
* @throws IllegalArgumentException if bean is null
|
||||
*
|
||||
* @see java.util.concurrent.locks.ReentrantLock#tryLock(long, java.util.concurrent.TimeUnit)
|
||||
*/
|
||||
public boolean tryLockUnrestricted(final KP key, final long timeout, final TimeUnit unit) throws InterruptedException {
|
||||
checkStopped();
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
boolean tryLockResultBoolean = false;
|
||||
try {
|
||||
final AtomicBoolean tryLockResult = new AtomicBoolean();
|
||||
final AtomicReference<InterruptedException> interruptedExceptionFromTryRef = new AtomicReference<InterruptedException>();
|
||||
final CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
|
||||
Callable<Boolean> callable = new Callable<Boolean>() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.util.concurrent.Callable#call()
|
||||
*/
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
boolean locked = false;
|
||||
try {
|
||||
locked = locker.tryLock(key, timeout, unit);
|
||||
tryLockResult.set(locked);
|
||||
} catch (InterruptedException e) {
|
||||
interruptedExceptionFromTryRef.set(e);
|
||||
return false;
|
||||
} finally {
|
||||
// STEP 1
|
||||
cyclicBarrier.await();
|
||||
}
|
||||
if (locked) {
|
||||
// STEP 2
|
||||
cyclicBarrier.await();
|
||||
return locker.unlock(key);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
Future<Boolean> futureTask = threadPool.submit(callable);
|
||||
try {
|
||||
// STEP 1
|
||||
cyclicBarrier.await();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
InterruptedException interruptedExceptionFromTry = interruptedExceptionFromTryRef.get();
|
||||
if (interruptedExceptionFromTry != null) {
|
||||
throw interruptedExceptionFromTry;
|
||||
}
|
||||
tryLockResultBoolean = tryLockResult.get();
|
||||
if (tryLockResultBoolean) {
|
||||
LockerValue<KP> lockerValue = locker.getLockerValue(key);
|
||||
Thread threadLocker = Thread.currentThread();
|
||||
lockerValue.addHandler(new LockerValueHandler(futureTask, cyclicBarrier, threadLocker));
|
||||
locker.traceStackForDebugging(lockerValue);
|
||||
}
|
||||
} finally {
|
||||
decrementRunningOperations();
|
||||
}
|
||||
|
||||
return tryLockResultBoolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "unlock". Unlock the operations with the provided key.
|
||||
*
|
||||
* To detect incorrect unlocking, this method may return an <code>IllegalStateException</code> when the lock has
|
||||
* been already unlocked or it never been locked.
|
||||
*
|
||||
* @param key
|
||||
* @return true if the key has been found to release the lock; and false otherwise
|
||||
* @throws IllegalStateException
|
||||
* @see java.util.concurrent.locks.ReentrantLock#unlock()
|
||||
*/
|
||||
@Override
|
||||
public boolean unlock(final KP key) {
|
||||
boolean returnedValue = false;
|
||||
try {
|
||||
checkStopped();
|
||||
blockOperationIfRequired();
|
||||
incrementRunningOperations();
|
||||
returnedValue = locker.unlock(key);
|
||||
} finally {
|
||||
decrementRunningOperations();
|
||||
}
|
||||
cleanAccordingOperations();
|
||||
return returnedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method "unlockUnrestricted". Unlock the operations with the provided key.
|
||||
*
|
||||
* To detect incorrect unlocking, this method may return an <code>IllegalStateException</code> when the lock has
|
||||
* been already unlocked or it never been locked.
|
||||
*
|
||||
* @param key
|
||||
* @return true if the key has been found to release the lock; and false otherwise
|
||||
* @throws IllegalStateException
|
||||
* @see java.util.concurrent.locks.ReentrantLock#unlock()
|
||||
*/
|
||||
public boolean unlockUnrestricted(final KP key) {
|
||||
checkStopped();
|
||||
blockOperationIfRequired();
|
||||
Boolean resultFuture;
|
||||
incrementRunningOperations();
|
||||
try {
|
||||
LockerValue<KP> lockerValue = locker.getLockerValue(key);
|
||||
if (lockerValue == null) {
|
||||
throw new IllegalStateException(NOT_ALREADY_LOCKED_MESSAGE + " key=" + key);
|
||||
}
|
||||
LockerValueHandler handler = lockerValue.getHandlerAndRemove();
|
||||
if (handler == null) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Either you have to use the restricted unlock() method to unlock, or you have to use '*Lock*Unrestricted()' methods to lock !");
|
||||
}
|
||||
CyclicBarrier barrier = handler.getBarrier();
|
||||
try {
|
||||
// STEP 2
|
||||
barrier.await();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
Future<Boolean> future = handler.getFuture();
|
||||
if (future.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
resultFuture = null;
|
||||
try {
|
||||
resultFuture = future.get();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} finally {
|
||||
decrementRunningOperations();
|
||||
}
|
||||
cleanAccordingOperations();
|
||||
return resultFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCleanPeriod() {
|
||||
return cleanPeriod;
|
||||
}
|
||||
|
||||
private void checkStopped() {
|
||||
if (stopped || shuttingDown) {
|
||||
throw new IllegalStateException("This locker is already stopped or is shutting down !");
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanAccordingOperations() {
|
||||
synchronized (lockAllOperations) {
|
||||
int cleanPeriod = getCleanPeriod();
|
||||
if (cleanPeriod > 0 && counter.incrementAndGet() % cleanPeriod == 0) {
|
||||
clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "clean".
|
||||
*
|
||||
* Clean the map which contains the lock wrappers.
|
||||
*
|
||||
* Removed lock wrappers are these where lock is not locked by a thread and no one thread is waiting to obtain the
|
||||
* lock.
|
||||
*
|
||||
* The default clean will do an automatic clean all 1000 unlock operation, you can disable or change this value from
|
||||
* the constructor.
|
||||
*/
|
||||
@Override
|
||||
public void clean() {
|
||||
synchronized (lockAllOperations) {
|
||||
waitForRunningOperationsEnded();
|
||||
locker.clean();
|
||||
resumeAllOperations();
|
||||
}
|
||||
}
|
||||
|
||||
private void waitForRunningOperationsEnded() {
|
||||
blockAllOperations();
|
||||
boolean breakAtNext = false;
|
||||
while (true) {
|
||||
Collection<LockerValue<KP>> values = locker.mapKeyLockToValueLock.values();
|
||||
int waitingThreads = 0;
|
||||
for (LockerValue<KP> lockerValue : values) {
|
||||
waitingThreads += lockerValue.getLock().getQueueLength();
|
||||
}
|
||||
if (runningOperations.get() - waitingThreads <= 0) {
|
||||
if (breakAtNext) {
|
||||
break;
|
||||
}
|
||||
breakAtNext = true;
|
||||
} else {
|
||||
breakAtNext = false;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resumeAllOperations() {
|
||||
this.blockAllOperations = false;
|
||||
lockAllOperations.notifyAll();
|
||||
}
|
||||
|
||||
private void blockAllOperations() {
|
||||
this.blockAllOperations = true;
|
||||
}
|
||||
|
||||
private void blockOperationIfRequired() {
|
||||
if (blockAllOperations) {
|
||||
synchronized (lockAllOperations) {
|
||||
if (blockAllOperations) {
|
||||
try {
|
||||
lockAllOperations.wait();
|
||||
} catch (InterruptedException e) {
|
||||
log.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void decrementRunningOperations() {
|
||||
runningOperations.decrementAndGet();
|
||||
}
|
||||
|
||||
private void incrementRunningOperations() {
|
||||
runningOperations.incrementAndGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void shutdown() {
|
||||
shuttingDown = true;
|
||||
locker.shutdown();
|
||||
threadPool.shutdown();
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockerValue<KP> getLockerValue(KP key) {
|
||||
return locker.getLockerValue(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocked(KP key) {
|
||||
return locker.isLocked(key);
|
||||
}
|
||||
|
||||
public List<LockerValue<KP>> getSuspectLocks(long timeDetectionLimitMs) {
|
||||
return locker.getSuspectLocks(timeDetectionLimitMs);
|
||||
}
|
||||
|
||||
public void setDetectSuspectLocks(boolean detectSuspectLocks) {
|
||||
locker.setDetectSuspectLocks(detectSuspectLocks);
|
||||
}
|
||||
|
||||
public boolean isDetectSuspectLocks() {
|
||||
return locker.isDetectSuspectLocks();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
package org.talend.commons.utils.threading.lockerbykey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.talend.commons.utils.StringUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* LockerValue.<br/>
|
||||
*
|
||||
* @param <VKP> key
|
||||
*/
|
||||
public class LockerValue<VKP> {
|
||||
|
||||
private CustomReentrantLock lock;
|
||||
|
||||
private VKP key;
|
||||
|
||||
private List<LockerValueHandler> handlers;
|
||||
|
||||
private StackTraceElement[] stackTraceOfLocker;
|
||||
|
||||
private long lockedTime;
|
||||
|
||||
/**
|
||||
* LockerValue constructor.
|
||||
*
|
||||
* @param thread
|
||||
* @param contextInfo
|
||||
* @param fair
|
||||
*/
|
||||
public LockerValue(VKP key, boolean fair) {
|
||||
this.lock = new CustomReentrantLock(fair);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return StringUtils.replacePrms("LockerValue: key={0}, lock={1}", String.valueOf(key), lock.toString()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for key.
|
||||
*
|
||||
* @return the key
|
||||
*/
|
||||
public VKP getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for lock.
|
||||
*
|
||||
* @return the lock
|
||||
*/
|
||||
public CustomReentrantLock getLock() {
|
||||
return lock;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "addHandler". Add handler to internal list.
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public synchronized void addHandler(LockerValueHandler handler) {
|
||||
if (handlers == null) {
|
||||
handlers = new ArrayList<LockerValueHandler>();
|
||||
}
|
||||
handlers.add(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "getHandlerAndRemove".
|
||||
*
|
||||
* Return the next available handler then remove it from internal list, else null if not exist.
|
||||
*
|
||||
* @return the next available handler, else null if not exist
|
||||
*/
|
||||
public synchronized LockerValueHandler getHandler() {
|
||||
if (handlers != null && handlers.size() > 0) {
|
||||
LockerValueHandler lockerValueHandler = handlers.get(0);
|
||||
return lockerValueHandler;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method "getHandlerAndRemove".
|
||||
*
|
||||
* Return the next available handler then remove it from internal list, else null if not exist.
|
||||
*
|
||||
* @return the next available handler, else null if not exist
|
||||
*/
|
||||
public synchronized LockerValueHandler getHandlerAndRemove() {
|
||||
if (handlers != null && handlers.size() > 0) {
|
||||
LockerValueHandler lockerValueHandler = handlers.get(0);
|
||||
handlers.remove(0);
|
||||
return lockerValueHandler;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for stackTraceElements.
|
||||
*
|
||||
* @return the stackTraceElements
|
||||
*/
|
||||
public StackTraceElement[] getStackTraceOfLocker() {
|
||||
return stackTraceOfLocker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stackTraceElements.
|
||||
*
|
||||
* @param stackTraceElements the stackTraceElements to set
|
||||
*/
|
||||
public void setStackTraceOfLocker(StackTraceElement[] stackTraceElements) {
|
||||
this.stackTraceOfLocker = stackTraceElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for lockedTime.
|
||||
*
|
||||
* @return the lockedTime
|
||||
*/
|
||||
public long getLockedTime() {
|
||||
return lockedTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the lockedTime.
|
||||
*
|
||||
* @param lockedTime the lockedTime to set
|
||||
*/
|
||||
public void setLockedTime(long lockedTime) {
|
||||
this.lockedTime = lockedTime;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
package org.talend.commons.utils.threading.lockerbykey;
|
||||
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* class LockerValueHandler.
|
||||
*/
|
||||
public class LockerValueHandler {
|
||||
|
||||
private Future<Boolean> future;
|
||||
|
||||
private CyclicBarrier barrier;
|
||||
|
||||
private Thread callerThreadLocker;
|
||||
|
||||
public LockerValueHandler(Future<Boolean> future, CyclicBarrier barrier, Thread callerThreadLocker) {
|
||||
super();
|
||||
this.future = future;
|
||||
this.barrier = barrier;
|
||||
this.callerThreadLocker = callerThreadLocker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for future.
|
||||
*
|
||||
* @return the future
|
||||
*/
|
||||
public Future<Boolean> getFuture() {
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for barrier.
|
||||
*
|
||||
* @return the barrier
|
||||
*/
|
||||
public CyclicBarrier getBarrier() {
|
||||
return barrier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for callerThreadLocker.
|
||||
*
|
||||
* @return the callerThreadLocker
|
||||
*/
|
||||
public Thread getCallerThreadLocker() {
|
||||
return callerThreadLocker;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry exported="true" kind="lib" path="lib/powermock-classloading-base-1.4.11.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/powermock-classloading-objenesis-1.4.11.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/powermock-classloading-xstream-1.4.11.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/powermock-easymock-1.4.11-full.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/powermock-mockito-1.4.11-full.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/powermock-module-junit4-rule-1.4.11.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/powermock-module-junit4-rule-agent-1.4.11.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"/>
|
||||
|
||||
@@ -4,9 +4,13 @@ Bundle-Name: Test
|
||||
Bundle-SymbolicName: org.talend.commons.test
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Fragment-Host: org.talend.commons;bundle-version="2.2.0"
|
||||
Require-Bundle: org.talend.testutils
|
||||
Bundle-ClassPath: .
|
||||
Export-Package: org.talend.commons.utils.data.list,
|
||||
org.talend.commons.utils.io,
|
||||
org.talend.commons.utils.time,
|
||||
org.talend.commons.utils.tracer
|
||||
Require-Bundle: org.junit4,
|
||||
org.mockito
|
||||
Bundle-ClassPath: .,
|
||||
lib/powermock-classloading-base-1.4.11.jar,
|
||||
lib/powermock-classloading-objenesis-1.4.11.jar,
|
||||
lib/powermock-classloading-xstream-1.4.11.jar,
|
||||
lib/powermock-easymock-1.4.11-full.jar,
|
||||
lib/powermock-mockito-1.4.11-full.jar,
|
||||
lib/powermock-module-junit4-rule-1.4.11.jar,
|
||||
lib/powermock-module-junit4-rule-agent-1.4.11.jar
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
||||
.,\
|
||||
lib/powermock-classloading-base-1.4.11.jar,\
|
||||
lib/powermock-classloading-objenesis-1.4.11.jar,\
|
||||
lib/powermock-classloading-xstream-1.4.11.jar,\
|
||||
lib/powermock-easymock-1.4.11-full.jar,\
|
||||
lib/powermock-mockito-1.4.11-full.jar,\
|
||||
lib/powermock-module-junit4-rule-1.4.11.jar,\
|
||||
lib/powermock-module-junit4-rule-agent-1.4.11.jar
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
org.talend.commons.test/lib/powermock-easymock-1.4.11-full.jar
Normal file
BIN
org.talend.commons.test/lib/powermock-easymock-1.4.11-full.jar
Normal file
Binary file not shown.
BIN
org.talend.commons.test/lib/powermock-mockito-1.4.11-full.jar
Normal file
BIN
org.talend.commons.test/lib/powermock-mockito-1.4.11-full.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -23,11 +23,15 @@ import static org.powermock.api.support.membermodification.MemberModifier.stub;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.soap.Node;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
@@ -45,6 +49,42 @@ public class FilesUtilsTest {
|
||||
@Rule
|
||||
public PowerMockRule powerMockRule = new PowerMockRule();
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.talend.commons.utils.io.FilesUtils#migrateFolder(java.io.File, java.lang.String[], java.util.Map, org.apache.log4j.Logger)}
|
||||
* .
|
||||
*/
|
||||
@Test
|
||||
public void testMigrateFolder() {
|
||||
File fileMdmConnection = new File(
|
||||
"/Talend/Talend_All_trunk/runtime/TOP_runtime/TOP_DEFAULT_PRJ/TDQ_Metadata/MDM Connections");
|
||||
|
||||
String[] mdmFileExtentionNames = { ".prv" };
|
||||
|
||||
Map<String, String> replaceStringMap = new HashMap<String, String>();
|
||||
replaceStringMap.put("TdXMLDocument", "TdXmlSchema");
|
||||
replaceStringMap.put("TdXMLElement", "TdXmlElementType");
|
||||
|
||||
Logger log = Logger.getLogger(FilesUtils.class);
|
||||
|
||||
FilesUtils.migrateFolder(fileMdmConnection, mdmFileExtentionNames, replaceStringMap, log);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.talend.commons.utils.io.FilesUtils#migrateFolder(java.io.File, java.io.File, boolean, java.io.FileFilter,java.io.FileFilter, boolean, boolean, org.eclipse.core.runtime.IProgressMonitor)}
|
||||
* .
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void testCopyFolder() throws IOException {
|
||||
File source = new File("");
|
||||
File target = new File("");
|
||||
FilesUtils.copyFolder(source, target, false, null, null, true, null);
|
||||
assertTrue(!target.exists());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link org.talend.commons.utils.io.FilesUtils#getUUID(java.lang.String)}
|
||||
*/
|
||||
@@ -88,7 +128,7 @@ public class FilesUtilsTest {
|
||||
*/
|
||||
@Test
|
||||
public void testParse_1() throws Exception {
|
||||
String path = "分析导出\\Row_Count_0.1.definition";
|
||||
String path = "D:\\分析导出\\Row_Count_0.1.definition";
|
||||
FilesUtils.parse(path);
|
||||
}
|
||||
|
||||
@@ -100,7 +140,7 @@ public class FilesUtilsTest {
|
||||
*/
|
||||
@Test
|
||||
public void testParse_2() throws Exception {
|
||||
File f = new File("testParse.xml");
|
||||
File f = new File("D:\\testParse.xml");
|
||||
BufferedWriter output = new BufferedWriter(new FileWriter(f));
|
||||
String str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ "<dataquality.indicators.definition:IndicatorDefinition xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns:dataquality.indicators.definition=\"http://dataquality.indicators.definition\" xmi:id=\"_ccFOkBF2Ed2PKb6nEJEvhw\" name=\"Row Count1\" label=\"Row Count\">\n"
|
||||
|
||||
@@ -53,7 +53,6 @@ CellEditorDialogBehavior.textContent=...
|
||||
ColorStyledText.RedoItem.Text=Wiederherstellen
|
||||
ColorStyledText.UndoItem.Text=Rückgängig
|
||||
ContentProposalAdapterExtended.close=Schließen
|
||||
DateDialog.textContent=Wähle Datum und Zeit
|
||||
EventUtil.activate=Aktivieren
|
||||
EventUtil.close=Schließen
|
||||
EventUtil.deactivate=Deaktivieren
|
||||
|
||||
@@ -14,7 +14,6 @@ package org.talend.commons.ui.swt.advanced.dataeditor.button;
|
||||
|
||||
import org.eclipse.gef.commands.Command;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.talend.commons.ui.runtime.i18n.Messages;
|
||||
import org.talend.commons.ui.runtime.image.EImage;
|
||||
import org.talend.commons.ui.runtime.image.ImageProvider;
|
||||
@@ -41,13 +40,6 @@ public abstract class CopyPushButton extends ExtendedPushButton {
|
||||
Messages.getString("CopyPushButton.CopyButton.Tip"), ImageProvider.getImage(EImage.COPY_ICON)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
protected void handleSelectionEvent(Event event) {
|
||||
Command commandToExecute = getCommandToExecute();
|
||||
if (commandToExecute != null) {
|
||||
commandToExecute.execute();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Command getCommandToExecute();
|
||||
|
||||
/*
|
||||
|
||||
@@ -16,7 +16,6 @@ import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.eclipse.gef.commands.CommandStack;
|
||||
import org.eclipse.jface.viewers.ILazyContentProvider;
|
||||
import org.eclipse.jface.viewers.TableViewer;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.DisposeEvent;
|
||||
@@ -296,7 +295,7 @@ public abstract class AbstractExtendedTableViewer<B> extends AbstractExtendedCon
|
||||
tableViewerCreator.getSelectionHelper().setSelection(event.index,
|
||||
event.index + event.addedObjects.size() - 1);
|
||||
} else if (event.indicesTarget != null) {
|
||||
int[] selection = ArrayUtils.toPrimitive(event.indicesTarget.toArray(new Integer[0]));
|
||||
int[] selection = ArrayUtils.toPrimitive((Integer[]) event.indicesTarget.toArray(new Integer[0]));
|
||||
tableViewerCreator.getSelectionHelper().setSelection(selection);
|
||||
|
||||
}
|
||||
@@ -319,7 +318,7 @@ public abstract class AbstractExtendedTableViewer<B> extends AbstractExtendedCon
|
||||
|
||||
} else if (event.type == TYPE.SWAPED) {
|
||||
if (event.indicesTarget != null) {
|
||||
int[] selection = ArrayUtils.toPrimitive(event.indicesTarget.toArray(new Integer[0]));
|
||||
int[] selection = ArrayUtils.toPrimitive((Integer[]) event.indicesTarget.toArray(new Integer[0]));
|
||||
tableViewerCreator.getSelectionHelper().setSelection(selection);
|
||||
}
|
||||
}
|
||||
@@ -375,11 +374,8 @@ public abstract class AbstractExtendedTableViewer<B> extends AbstractExtendedCon
|
||||
}).start();
|
||||
} else {
|
||||
|
||||
// tableViewer.refresh();
|
||||
if (event.type == TYPE.ADDED) {
|
||||
if (tableViewer.getContentProvider() instanceof ILazyContentProvider) {
|
||||
tableViewer.setItemCount(event.source.size());
|
||||
}
|
||||
tableViewer.refresh();
|
||||
|
||||
} else if (event.type == TYPE.SWAPED) {
|
||||
|
||||
@@ -387,7 +383,8 @@ public abstract class AbstractExtendedTableViewer<B> extends AbstractExtendedCon
|
||||
|
||||
Object[] swapedObjects = event.swapedObjects;
|
||||
|
||||
for (Object data : swapedObjects) {
|
||||
for (int j = 0; j < swapedObjects.length; j++) {
|
||||
Object data = swapedObjects[j];
|
||||
tableViewer.refresh(data, true, true);
|
||||
}
|
||||
|
||||
@@ -405,9 +402,6 @@ public abstract class AbstractExtendedTableViewer<B> extends AbstractExtendedCon
|
||||
// tableViewer.refresh(bean);
|
||||
// }
|
||||
} else {
|
||||
if (tableViewer.getContentProvider() instanceof ILazyContentProvider) {
|
||||
tableViewer.setItemCount(event.source.size());
|
||||
}
|
||||
tableViewer.refresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,4 +17,3 @@ Export-Package: org.talend.commons.utils.generation,
|
||||
org.talend.commons.utils.workbench.resources
|
||||
Bundle-Vendor: .Talend SA.
|
||||
Bundle-ClassPath: .
|
||||
Eclipse-RegisterBuddy: org.talend.testutils
|
||||
|
||||
@@ -44,7 +44,6 @@ import java.util.zip.ZipFile;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
@@ -312,10 +311,8 @@ public class FilesUtils {
|
||||
BufferedReader buf = new BufferedReader(inR);
|
||||
String line;
|
||||
while ((line = buf.readLine()) != null) {
|
||||
buffer.append(StringUtils.replace(line, regex, replacement)).append("\n"); //$NON-NLS-1$
|
||||
buffer.append(line.replaceAll(regex, replacement)).append("\n"); //$NON-NLS-1$
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
@@ -326,6 +323,22 @@ public class FilesUtils {
|
||||
}
|
||||
|
||||
public static List<URL> getFilesFromFolder(Bundle bundle, String path, String extension) {
|
||||
// List<URL> toReturn = new ArrayList<URL>();
|
||||
//
|
||||
// Enumeration entryPaths = bundle.getEntryPaths(path);
|
||||
// for (Enumeration enumer = entryPaths; enumer.hasMoreElements();) {
|
||||
// String fileName = (String) enumer.nextElement();
|
||||
// if (fileName.endsWith(extension)) {
|
||||
// URL url = bundle.getEntry(fileName);
|
||||
// try {
|
||||
// toReturn.add(FileLocator.toFileURL(url));
|
||||
// } catch (IOException e) {
|
||||
// CommonExceptionHandler.process(e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return toReturn;
|
||||
|
||||
return getFilesFromFolder(bundle, path, extension, true, false);
|
||||
}
|
||||
|
||||
@@ -1017,30 +1030,4 @@ public class FilesUtils {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* rename the folder.
|
||||
*
|
||||
* @param srcfolder
|
||||
* @param targetfolder
|
||||
*/
|
||||
public static void renameFolder(File srcfolder, File targetfolder) {
|
||||
if (srcfolder.exists() && srcfolder.isDirectory()) {
|
||||
try {
|
||||
if (!targetfolder.exists()) {
|
||||
targetfolder.mkdirs();
|
||||
}
|
||||
File[] listFiles = srcfolder.listFiles();
|
||||
for (File file : listFiles) {
|
||||
if (file.isDirectory()) {
|
||||
copyDirectory(file, targetfolder);
|
||||
} else if (file.isFile()) {
|
||||
copyFile(file, targetfolder);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn(e, e);
|
||||
}
|
||||
deleteFile(srcfolder, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,6 @@ public final class ResourceUtils {
|
||||
List<IProject> projects = new ArrayList<IProject>();
|
||||
for (IProject prj : allProjects) {
|
||||
try {
|
||||
prj.open(IResource.BACKGROUND_REFRESH, null);
|
||||
if (prj.hasNature(natureId)) {
|
||||
projects.add(prj);
|
||||
}
|
||||
|
||||
@@ -428,9 +428,11 @@ ConnectionParameters.exceptionMessage=This is a repository , should not call thi
|
||||
GenerateSelectSQLAction.NewQuery=new Query {0}
|
||||
ConnectionParameterName.HostLabel=Host
|
||||
ConnectionParameterName.PortLabel=Port
|
||||
ConnectionParameterName.DatabaseLabel=Database
|
||||
ConnectionParameterName.SchemaLabel=Schema
|
||||
ConnectionParameterName.UserLabel=User
|
||||
ConnectionParameterName.PasswordLabel=Password
|
||||
ConnectionParameterName.DbfileLabel=Database
|
||||
ConnectionParameterName.DbPathLabel=DataBase Root Path
|
||||
HTMLDocGenerator.tmap.expressionfilter=expressionFilter
|
||||
AbstractBrandingService.routines_license_header_content1=Copyright (c) 2005-2012, Talend Inc.\n//\n// This source code has been automatically generated by_{0}\n// CodeGenerator version {1}\n// You can find more information about Talend products at www.talend.com.\n// You may distribute this code under the terms of the GNU LGPL license\n// http://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
@@ -358,7 +358,6 @@ HTMLDocGenerator.ended=termin
|
||||
HTMLDocGenerator.extra_settings=Paramètres supplémentaires
|
||||
HTMLDocGenerator.generation_date=Date de génération
|
||||
HTMLDocGenerator.job_description=Description
|
||||
HTMLDocGenerator.job_preview_picture=Aperçu
|
||||
HTMLDocGenerator.job_settings=Paramètres
|
||||
HTMLDocGenerator.key=Clé
|
||||
HTMLDocGenerator.label=Libellé
|
||||
@@ -369,9 +368,7 @@ HTMLDocGenerator.mapper.expression=Expression
|
||||
HTMLDocGenerator.mapper.join.type=Type de jointure
|
||||
HTMLDocGenerator.mapper.metadatatable.entries=Entrées de la table des métadonnées
|
||||
HTMLDocGenerator.mapper.operator=Opérateur
|
||||
HTMLDocGenerator.mapper.table.for=Table de mapping de
|
||||
HTMLDocGenerator.mapper.table.name=Nom de la table
|
||||
HTMLDocGenerator.mapper.table.properties=Propriétés de la table de mapping
|
||||
HTMLDocGenerator.modification=Modification
|
||||
HTMLDocGenerator.name=Nom
|
||||
HTMLDocGenerator.nullable=Nullable
|
||||
@@ -383,7 +380,6 @@ HTMLDocGenerator.properties=Propri
|
||||
HTMLDocGenerator.purpose=Objectif
|
||||
HTMLDocGenerator.row_default=Aucune
|
||||
HTMLDocGenerator.row_functions=Fonctions
|
||||
HTMLDocGenerator.row_generator_info=Informations du générateur de lignes de
|
||||
HTMLDocGenerator.row_parameters=Paramètres
|
||||
HTMLDocGenerator.schema_for=Schéma de
|
||||
HTMLDocGenerator.source=Source
|
||||
@@ -400,8 +396,10 @@ ConnectionParameters.exceptionMessage=Ceci est un r
|
||||
GenerateSelectSQLAction.NewQuery=nouvelle requête {0}
|
||||
ConnectionParameterName.HostLabel=Hôte
|
||||
ConnectionParameterName.PortLabel=Port
|
||||
ConnectionParameterName.DatabaseLabel=Base de données
|
||||
ConnectionParameterName.SchemaLabel=Schéma
|
||||
ConnectionParameterName.UserLabel=Utilisateur
|
||||
ConnectionParameterName.PasswordLabel=Mot de passe
|
||||
ConnectionParameterName.DbfileLabel=Base de données
|
||||
ConnectionParameterName.DbPathLabel=Chemin d'accès racine à la base de données
|
||||
AbstractBrandingService.routines_license_header_content1=Copyright (c) 2005-2012, Talend Inc.\n//\n// Ce code source a été automatiquement généré par_{0}\n// CodeGenerator version {1}\n// Pour plus d'informations concernant les produits Talend, consultez www.talend.com.\n// Vous pouvez distribuer ce code sous conditions de la licence GNU LGPL\n// http://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
@@ -173,7 +173,6 @@ ContextSetConfigurationDialog.nameNotValid=\u540D\u79F0\u304C\u6B63\u3057\u304F\
|
||||
ComponentsFormatPreferencePage.remove=\u524A\u9664
|
||||
ComponentToRepositoryProperty.error=\u30A8\u30E9\u30FC
|
||||
ComponentToRepositoryProperty.ImpossibleUseOCI=\u30EC\u30DD\u30B8\u30C8\u30EA\u306EOCI\u30BF\u30A4\u30D7\u304C\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093\u3002
|
||||
ContextComposite.tableValue=\u30C6\u30FC\u30D6\u30EB\u3068\u3057\u3066\u306E\u5024
|
||||
ContextComposite.tableValue=\u30C6\u30FC\u30D6\u30EB\u3068\u3057\u3066\u306E\u5024
|
||||
ContextComposite.treeValue=tree\u3068\u3057\u3066\u306E\u5024
|
||||
ContextComposite.variable=\u5909\u6570
|
||||
@@ -230,17 +229,10 @@ ContextTreeConstants.variableName=\u5909\u6570
|
||||
ContextTemplateComposite.scriptCodeLabel=\u30B9\u30AF\u30EA\u30D7\u30C8\u30B3\u30FC\u30C9
|
||||
ContextTemplateComposite.sourceLabel=\u30BD\u30FC\u30B9
|
||||
ContextTemplateComposite.typeLabel=\u30BF\u30A4\u30D7
|
||||
ContextTreeConstants.contextName=\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8
|
||||
ContextTreeConstants.contextName=\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8
|
||||
ContextTreeConstants.valueName=\u5024
|
||||
ContextTreeConstants.promptName=\u30D7\u30ED\u30F3\u30D7\u30C8
|
||||
XPathQueryMetadataTableEditorViewExt.xpathQuerys=XPathQuerys\u30B9\u30AD\u30FC\u30DE
|
||||
CorePreferencePage.alwaysWelcome=\u30B9\u30BF\u30FC\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u30A6\u30A7\u30EB\u30AB\u30E0\u30D3\u30E5\u30FC\u3092\u5E38\u306B\u8868\u793A
|
||||
MetadataTool.errorMessage=\u3053\u306E\u6587\u5B57\u306F\u5165\u529B\u3067\u304D\u307E\u305B\u3093\u3002
|
||||
MetadataTool.invalid=\u4E0D\u6B63\u306A\u5024\u3067\u3059\u3002
|
||||
ContextTreeConstants.valueName=\u5024
|
||||
ContextTreeConstants.variableName=\u5909\u6570
|
||||
MetadataTool.nullValue=Null\u5024
|
||||
XPathQueryMetadataTableEditorViewExt.xpathQuerys=XPathQuerys\u30B9\u30AD\u30FC\u30DE
|
||||
CorePreferencePage.alwaysWelcome=\u30B9\u30BF\u30FC\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u30A6\u30A7\u30EB\u30AB\u30E0\u30D3\u30E5\u30FC\u3092\u5E38\u306B\u8868\u793A
|
||||
MetadataTool.errorMessage=\u3053\u306E\u6587\u5B57\u306F\u5165\u529B\u3067\u304D\u307E\u305B\u3093\u3002
|
||||
|
||||
@@ -7,14 +7,13 @@ EUpdateItemType.Name=\uC774\uB984
|
||||
AbstractComponentsProvider.folderNotExist=\uD3F4\uB354{0}\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC74C.
|
||||
VariableItemEditor.name=\uC774\uB984
|
||||
ApplicationActionBarAdvisor.menuFileLabel=\uD30C\uC77C\uBA54\uB274
|
||||
ApplicationActionBarAdvisor.menuWindowLabel=\uC708\uB3C4\uC6B0
|
||||
ApplicationActionBarAdvisor.menuWindowLabel=\uC708\uB3C4\uC6B0\uBA54\uB274
|
||||
ApplicationActionBarAdvisor.menuHelpLabel=\uB3C4\uC6C0\uB9D0\uBA54\uB274
|
||||
ConextTableValuesComposite.nameLabel=\uC774\uB984
|
||||
ContextTemplateComposite.CommentLabel=1rdrhdh
|
||||
ContextTemplateComposite.nameLabel=\uC774\uB984
|
||||
ContextTemplateComposite.sourceLabel=\uC6D0\uBCF8
|
||||
ContextTreeConstants.valueName=\uAC12
|
||||
EComponentCategory_assignment=\uBC30\uC815
|
||||
EComponentCategory_sqlTemplate=SQL \uD15C\uD50C\uB9BF
|
||||
EComponentCategory_version=\uBC84\uC83C
|
||||
HTMLDocGenerator.comment=1rdrhdh
|
||||
|
||||
@@ -66,7 +66,7 @@ EConnectionType.mergeMenu=\u5408\u5E76
|
||||
ColorsCodeViewerPreferencePage.Comment1Color=\u6CE8\u91CA1 \u989C\u8272
|
||||
RoutinesFunctionProposal.VariableName=\n\n\u53D8\u91CF\u540D\uFF1A {2}
|
||||
RepositoryUpdateManager.RenameContextTitle=\u91CD\u547D\u540D\u95EE\u9898
|
||||
EUpdateItemType.Schema=\u67B6\u6784
|
||||
EUpdateItemType.Schema=RowGenerator\u53C2\u6570\u8868
|
||||
MetadataEmfTableEditor.ColumnNameExists=\u5217\u540D{0}\u5DF2\u5B58\u5728\u3002
|
||||
Parameter.Name=\u53C2\u6570\u540D
|
||||
FunctionManager.PurePerl.ParaName=\u81EA\u5B9A\u4E49\u53C2\u6570
|
||||
@@ -201,7 +201,7 @@ SchemaOperationChoiceDialog.CreateBuiltInMessage=Built-in\u4E2D\u521B\u5EFA\u56F
|
||||
SchemaOperationChoiceDialog.CreateRepositoryMessage=\u4ECE\u5E93\u4E2D\u521B\u5EFA\u56FE\u89E3\u3002
|
||||
SchemaOperationChoiceDialog.EditSchemaMessage=\u7F16\u8F91\u67B6\u6784
|
||||
SchemaOperationChoiceDialog.StatusMessage=\u65E0\u6548\u6216\u5DF2\u5B58\u5728\u7684\u56FE\u89E3
|
||||
SchemaOperationChoiceDialog.Title=\u67B6\u6784
|
||||
SchemaOperationChoiceDialog.Title=RowGenerator\u53C2\u6570\u8868
|
||||
VariableItemEditor.name=\u57fa\u672c\u6570\u636e\u540d
|
||||
VariableItemEditor.new=\u65b0
|
||||
VariableItemEditor.remove=\u79FB\u9664
|
||||
@@ -286,7 +286,7 @@ HTMLDocGenerator.version=\u7248\u672C
|
||||
ConnectionParameters.exceptionMessage=\u8FD9\u662F\u50A8\u5B58\u5E93\uFF0C\u4E0D\u80FD\u8C03\u7528\u4E9B\u65B9\u6CD5\u3002
|
||||
ConnectionParameterName.HostLabel=\u4e3b\u673a
|
||||
ConnectionParameterName.PortLabel=\u7aef\u53e3
|
||||
ConnectionParameterName.SchemaLabel=\u67B6\u6784
|
||||
ConnectionParameterName.SchemaLabel=\u56fe\u89e3\u5217\u8868
|
||||
ConnectionParameterName.UserLabel=\u7528\u6237
|
||||
ConnectionParameterName.PasswordLabel=\u5bc6\u7801
|
||||
ConnectionParameterName.DbPathLabel=\u6570\u636E\u5E93\u7684\u6839\u8DEF\u5F84
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=\u0644\u0627\u064A\u0645\u0643\u0646 \u062A\u0648\u0644\u064A\u062F \u0639\u0646\u0648\u0627\u0646 \u0645\u0627\u062F\u0629 \u0628\u0627\u0644\u0644\u0635\u0642
|
||||
AbstractEMFRepositoryFactory.presistenceException.whoCauseProblems=\u0627\u0644\u0645\u0634\u0627\u0643\u0644 \u0628\u0633\u0628\u0628 \u0627\u0644\u0639\u0646\u0627\u0635\u0631 \u0627\u0644\u062A\u0627\u0644\u064A\u0629:
|
||||
ProxyRepositoryFactory.Label=\u062A\u0633\u0645\u064A\u0629
|
||||
CreateSandboxProjectDialog.ProjectLabel=\u062A\u0633\u0645\u064A\u0629
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=\u0394\u03B5 \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF \u03BD\u03B1 \u03C0\u03B1\u03C1\u03B1\u03C7\u03B8\u03B5\u03AF \u03B5\u03C0\u03B9\u03BA\u03BF\u03BB\u03BB\u03BF\u03CD\u03BC\u03B5\u03BD\u03B7 \u03B5\u03C4\u03B9\u03BA\u03AD\u03C4\u03B1 \u03B1\u03BD\u03C4\u03B9\u03BA\u03B5\u03B9\u03BC\u03AD\u03BD\u03BF\u03C5
|
||||
AbstractEMFRepositoryFactory.job=\u0395\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1
|
||||
AbstractEMFRepositoryFactory.presistenceException.whoCauseProblems=\u03B1\u03BD\u03C4\u03B9\u03BA\u03B5\u03AF\u03BC\u03B5\u03BD\u03B1 \u03C0\u03BF\u03C5 \u03C0\u03C1\u03BF\u03BA\u03B1\u03BB\u03BF\u03CD\u03BD \u03C0\u03C1\u03BF\u03B2\u03BB\u03AE\u03BC\u03B1\u03C4\u03B1 \u03B5\u03AF\u03BD\u03B1\u03B9:
|
||||
ProxyRepositoryFactory.bussinessException.itemNonModifiable=\u0394\u03B5\u03BD \u03AD\u03C7\u03B5\u03C4\u03B5 \u03B1\u03C1\u03BA\u03B5\u03C4\u03AC \u03B4\u03B9\u03BA\u03B1\u03B9\u03CE\u03BC\u03B1\u03C4\u03B1 \u03B3\u03B9\u03B1 \u03B1\u03C5\u03C4\u03AE \u03C4\u03B7\u03BD \u03B5\u03BD\u03AD\u03C1\u03B3\u03B5\u03B9\u03B1
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=Cannot generate pasted item label.
|
||||
AbstractEMFRepositoryFactory.job=Job
|
||||
AbstractEMFRepositoryFactory.presistenceException.OnlyOneOccurenceMustbeFound=More than one items are retrieved at the same time.\n{0}
|
||||
AbstractEMFRepositoryFactory.presistenceException.whoCauseProblems=Items who cause problems are:
|
||||
@@ -144,3 +143,4 @@ RepositoryDropAdapter_moveTitle=Move
|
||||
RepositoryDropAdapter_movingItems=Moving items...
|
||||
RepositoryDropAdapter.checkingLockStatus=Checking lock status of
|
||||
RepositoryDropAdapter.moving=Moving
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=Cannot generate pasted item label.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=No Genero Etiqueta Pegada del Item
|
||||
AbstractEMFRepositoryFactory.job=Trabajo
|
||||
AbstractEMFRepositoryFactory.presistenceException.whoCauseProblems=Los elementos que causan problema son:
|
||||
AbstractEMFRepositoryFactory.requiredComponent=Requerido para utilizar el componente:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=Impossible de générer le libellé collé de l'élément
|
||||
AbstractEMFRepositoryFactory.job=Job
|
||||
AbstractEMFRepositoryFactory.presistenceException.OnlyOneOccurenceMustbeFound=Plusieurs éléments ont été retrouvés simultanément.\n{0}
|
||||
AbstractEMFRepositoryFactory.presistenceException.whoCauseProblems=Les éléments à l'origine des problèmes sont :
|
||||
@@ -64,9 +63,9 @@ EAuthenticationMethod.anonymousAuth=Authentification anonyme
|
||||
EAuthenticationMethod.simpleAuth=Authentification simple
|
||||
AdvancedSocketFactory.failedInitial=Erreur : impossible d'initialiser :
|
||||
LDAPCATruster.sslError1=Erreur SSL : échec de la vérification de la chaîne de certification du serveur.
|
||||
CopyAction.thisText.copy=Copier
|
||||
PasteAction.thisText.paste=Coller
|
||||
DeleteAction.action.foreverTitle=Supprimer définitivement
|
||||
DeleteAction.action.logicalTitle=Supprimer
|
||||
DeleteAction.action.logicalToolTipText=Placer l'élément dans la Corbeille
|
||||
DeleteAction.dialog.message0=sera supprimé(e) définitivement (pas de récupération possible).
|
||||
DeleteAction.dialog.message1=Les éléments sélectionnés seront supprimés définitivement (pas de récupération possible).
|
||||
@@ -93,19 +92,5 @@ JobletReferenceDialog.project=Projet
|
||||
JobletReferenceDialog.ReferenceJob=Job de référence
|
||||
JobletReferenceDialog.Title=Echec de la suppression du joblet
|
||||
EmptyRecycleBinAction.dialog.allDependencies=Vous ne pouvez vider la Corbeille.\nLa perspective Profiling dépend d'un élément. Ne le supprimez pas.
|
||||
DeleteAction.deleteJobAssignedToOneService=\ est assigné à une opération d'un Service.\nSupprimer le Job ?
|
||||
ContextReferenceDialog.Title=Supprimer l'échec du contexte
|
||||
ContextReferenceDialog.Recycle=dans la Corbeille
|
||||
ContextReferenceDialog.ReferenceJob=Objets de référence
|
||||
ContextReferenceDialog.Messages=Le contexte ({0} {1}) est référencé dans\:\n
|
||||
ProxyRepositoryFactory.ReplaceJobHazardDescription=\n Les dépendances de la connexion originale seront perdues.
|
||||
ProjectRepositoryNode.rulesManagement=Gestion des règles
|
||||
ProjectRepositoryNode.itemInvalid=Elément invalide : [{0}] {1}
|
||||
ProjectRepositoryNode.invalidItem=Elément invalide
|
||||
ProjectRepositoryNode.validationRules=Règles de validation
|
||||
ProjectRepositoryNode.genericSchema=Schémas génériques
|
||||
ProjectRepositoryNode.queries=Requêtes
|
||||
ProjectRepositoryNode.tableSchemas=Schémas des tables
|
||||
ProjectRepositoryNode.viewSchemas=Voir les schémas
|
||||
ProjectRepositoryNode.sapFunctions=Fonctions SAP
|
||||
ProjectRepositoryNode.sapIDocs=SAP iDocs
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=Ne mogu generirati naziv zaljepljene stavke.
|
||||
AbstractEMFRepositoryFactory.job=Posao
|
||||
AbstractEMFRepositoryFactory.presistenceException.whoCauseProblems=Stavke koje uzrokuju problem:
|
||||
ProxyRepositoryFactory.Label=Labela
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=Impossibile generare copia elemento
|
||||
AbstractEMFRepositoryFactory.job=Job
|
||||
ProxyRepositoryFactory.Label=Etichetta
|
||||
CreateSandboxProjectDialog.ProjectDesc=Descrizione
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=\u30A2\u30A4\u30C6\u30E0\u30E9\u30D9\u30EB\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F
|
||||
AbstractEMFRepositoryFactory.job=\u30B8\u30E7\u30D6
|
||||
AbstractEMFRepositoryFactory.presistenceException.OnlyOneOccurenceMustbeFound=time.n{0}\u3067\u540C\u6642\u306B1\u3064\u4EE5\u4E0A\u306E\u30A2\u30A4\u30C6\u30E0\u304C\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059
|
||||
AbstractEMFRepositoryFactory.presistenceException.whoCauseProblems=\u554F\u984C\u767A\u751F\u539F\u56E0\u306F\uFF1A
|
||||
AbstractEMFRepositoryFactory.requiredComponent=\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u4F7F\u7528\u8981\u6C42:
|
||||
AbstractEMFRepositoryFactory.requiredComponent=\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u4F7F\u7528\u8981\u6C42
|
||||
ProxyRepositoryFactory.bussinessException.itemNonModifiable=\u30A2\u30AF\u30B7\u30E7\u30F3\u306E\u6A29\u9650\u304C\u3042\u308A\u307E\u305B\u3093
|
||||
ProxyRepositoryFactory.exec.migration.tasks=\u79FB\u884C\u30BF\u30B9\u30AF\u3092\u5B9F\u884C\u3057\u307E\u3059
|
||||
ProxyRepositoryFactory.illegalArgumentException.labeAlreadyInUse=\u30E9\u30D9\u30EB{0}\u306F\u65E2\u306B\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=Nie mo\u017Cna wygenerowa\u0107 etykiety dla wklejanego obiektu.
|
||||
AbstractEMFRepositoryFactory.presistenceException.whoCauseProblems=Elementy powoduj\u0105ce problemy:
|
||||
AbstractEMFRepositoryFactory.requiredComponent=Wymagane u\u017Cycie komponentów:
|
||||
ProxyRepositoryFactory.Label=Etykieta
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=Impossível gerar label do item copiado
|
||||
AbstractEMFRepositoryFactory.presistenceException.whoCauseProblems=Quais são os itens que causaram problema:
|
||||
ProxyRepositoryFactory.initializeProjectConnection=Iniciar Conexão do Projeto
|
||||
ProxyRepositoryFactory.Label=Label
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
AbstractEMFRepositoryFactory.cannotGenerateItem=\u65E0\u6CD5\u751F\u6210\u7C98\u8D34\u9879\u76EE\u7684\u6807\u7B7E.
|
||||
AbstractEMFRepositoryFactory.job=\u4f5c\u4e1a
|
||||
ProxyRepositoryFactory.bussinessException.itemNonModifiable=\u4e0d\u53ef\u4fee\u6539\u9879
|
||||
ProxyRepositoryFactory.illegalArgumentException.labelNotMatchPattern=\u6807\u7b7e {0} \u4e0e\u6a21\u5f0f {1} \u4e0d\u7b26
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<extension-point id="repository_service" name="Repository service" schema="schema/repository_service.exsd"/>
|
||||
<extension-point id="metadata_provider" name="Metadata provider" schema="schema/metadata_provider.exsd"/>
|
||||
<extension-point id="org.talend.core.repository.login.task" name="Login Task" schema="schema/login_task.exsd"/>
|
||||
<extension-point id="checkDeleteItemReference" name="Check Delete Item Reference" schema="schema/checkDeleteItemReference.exsd"/>
|
||||
|
||||
<extension
|
||||
point="org.talend.core.runtime.service">
|
||||
@@ -580,12 +579,6 @@
|
||||
class="org.talend.core.repository.GeneratedJetEmitersLoginTask">
|
||||
</loginTask>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.talend.core.repository.checkDeleteItemReference">
|
||||
<check
|
||||
class="org.talend.core.repository.model.CheckJobletDeleteReference"
|
||||
priority="high">
|
||||
</check>
|
||||
</extension>
|
||||
|
||||
|
||||
</plugin>
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Schema file written by PDE -->
|
||||
<schema targetNamespace="org.talend.core.repository" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||
<annotation>
|
||||
<appinfo>
|
||||
<meta.schema plugin="org.talend.core.repository" id="checkDeleteItemReference" name="Check Delete Item Reference"/>
|
||||
</appinfo>
|
||||
<documentation>
|
||||
[Enter description of this extension point.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<annotation>
|
||||
<appinfo>
|
||||
<meta.element />
|
||||
</appinfo>
|
||||
</annotation>
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref="check" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</sequence>
|
||||
<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="check">
|
||||
<complexType>
|
||||
<attribute name="class" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appinfo>
|
||||
<meta.attribute kind="java" basedOn=":org.talend.core.repository.ICheckDeleteItemReference"/>
|
||||
</appinfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="priority">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
<simpleType>
|
||||
<restriction base="string">
|
||||
<enumeration value="lowest">
|
||||
</enumeration>
|
||||
<enumeration value="low">
|
||||
</enumeration>
|
||||
<enumeration value="normal">
|
||||
</enumeration>
|
||||
<enumeration value="high">
|
||||
</enumeration>
|
||||
<enumeration value="highest">
|
||||
</enumeration>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
</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>
|
||||
@@ -65,16 +65,16 @@ PropertiesWizardPage.Version.Minor=m
|
||||
PropertiesWizardPage.ImageSizeError=Please select image in size 32*32.
|
||||
EAuthenticationMethod.anonymousAuth=Anonymous Authentication
|
||||
EAuthenticationMethod.simpleAuth=Simple Authentication
|
||||
AdvancedSocketFactory.failedInitial=Error\: failed to initialize \:
|
||||
LDAPCATruster.failedCreateCert=Failed to create cert store \:
|
||||
LDAPCATruster.failedCreateTmp=Failed to create tmp trust store \:
|
||||
LDAPCATruster.failedInitialTrust=Failed to create initial trust manager \:
|
||||
LDAPCATruster.failedLoadCert=Failed to load the cert store \:
|
||||
LDAPCATruster.failedSaveTrust=Failed to save trust store \:
|
||||
LDAPCATruster.locationInvalid=The location of the cert store file is invalid\:
|
||||
AdvancedSocketFactory.failedInitial=Error: failed to initialize :
|
||||
LDAPCATruster.failedCreateCert=Failed to create cert store :
|
||||
LDAPCATruster.failedCreateTmp=Failed to create tmp trust store :
|
||||
LDAPCATruster.failedInitialTrust=Failed to create initial trust manager :
|
||||
LDAPCATruster.failedLoadCert=Failed to load the cert store :
|
||||
LDAPCATruster.failedSaveTrust=Failed to save trust store :
|
||||
LDAPCATruster.locationInvalid=The location of the cert store file is invalid:
|
||||
LDAPCATruster.noCertificate=\nPlease use the keytool command to import the server certificate.
|
||||
LDAPCATruster.sslError1=SSL Error:Server certificate chain verification failed.
|
||||
LDAPCATruster.sslError2=SSL Error\:Server certificate chain verification failed and \\nthe CA is missing.
|
||||
LDAPCATruster.sslError2=SSL Error:Server certificate chain verification failed and \\nthe CA is missing.
|
||||
LDAPCATruster.sslError3=SSL Error:CA certificate is not in the server certificate chain.
|
||||
CopyAction.thisText.copy=Copy
|
||||
RestoreAction.action.title=Restore
|
||||
@@ -122,16 +122,7 @@ ContextReferenceDialog.Types=Type
|
||||
ContextReferenceDialog.NodeTypeTip=The type of node reference
|
||||
ContextReferenceDialog.Messages=Context({0} {1}) is referenced from\:\n
|
||||
CopyToGenericSchemaHelper.cannotGenarateItem=Cannot generate pasted item label.
|
||||
ProxyRepositoryFactory.ReplaceJobHazardDescription=\nDependence on the original connection may be lost\!
|
||||
|
||||
ItemReferenceDialog.title=Items which cannot be deleted
|
||||
ItemReferenceDialog.item=Item
|
||||
ItemReferenceDialog.referenceItem=Reference Item
|
||||
ItemReferenceDialog.nodeTotals=Totals
|
||||
ItemReferenceDialog.nodeTotalsTip=The totals of node reference
|
||||
ItemReferenceDialog.project=Project
|
||||
ItemReferenceDialog.deletedInfor=In Recycle Bin
|
||||
ItemReferenceDialog.messages=Some items cannot be deleted because they are referenced from other items.
|
||||
ProxyRepositoryFactory.ReplaceJobHazardDescription=\nDependence on the original connection may be lost!
|
||||
|
||||
ProjectRepositoryNode.code=Code
|
||||
ProjectRepositoryNode.rulesManagement=Rules Management
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.core.repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.talend.repository.model.IRepositoryNode;
|
||||
import org.talend.repository.model.ItemReferenceBean;
|
||||
import org.talend.repository.ui.actions.DeleteActionCache;
|
||||
|
||||
/**
|
||||
* DOC ycbai class global comment. Detailled comment
|
||||
*/
|
||||
public interface ICheckDeleteItemReference {
|
||||
|
||||
public Set<ItemReferenceBean> getItemReferenceBeans(List<? extends IRepositoryNode> deleteNodes,
|
||||
DeleteActionCache deleteActionCache);
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
// ============================================================================
|
||||
//
|
||||
// Copyright (C) 2006-2012 Talend Inc. - www.talend.com
|
||||
//
|
||||
// This source code is available under agreement available at
|
||||
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
|
||||
//
|
||||
// You should have received a copy of the agreement
|
||||
// along with this program; if not, write to Talend SA
|
||||
// 9 rue Pages 92150 Suresnes, France
|
||||
//
|
||||
// ============================================================================
|
||||
package org.talend.core.repository.model;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.talend.core.model.properties.Property;
|
||||
import org.talend.core.model.repository.ERepositoryObjectType;
|
||||
import org.talend.core.model.repository.IRepositoryViewObject;
|
||||
import org.talend.core.repository.ICheckDeleteItemReference;
|
||||
import org.talend.repository.model.IProxyRepositoryFactory;
|
||||
import org.talend.repository.model.IRepositoryNode;
|
||||
import org.talend.repository.model.ItemReferenceBean;
|
||||
import org.talend.repository.ui.actions.DeleteActionCache;
|
||||
|
||||
/**
|
||||
* DOC ycbai class global comment. Detailled comment
|
||||
*/
|
||||
public abstract class AbstractCheckDeleteItemReference implements ICheckDeleteItemReference {
|
||||
|
||||
protected IProxyRepositoryFactory factory = ProxyRepositoryFactory.getInstance();
|
||||
|
||||
protected List<? extends IRepositoryNode> deleteNodes;
|
||||
|
||||
public Set<ItemReferenceBean> getItemReferenceBeans(List<? extends IRepositoryNode> deleteNodes,
|
||||
DeleteActionCache deleteActionCache) {
|
||||
this.deleteNodes = deleteNodes;
|
||||
Set<ItemReferenceBean> refBeans = new HashSet<ItemReferenceBean>();
|
||||
|
||||
if (deleteActionCache == null) {
|
||||
deleteActionCache = DeleteActionCache.getInstance();
|
||||
deleteActionCache.createRecords();
|
||||
}
|
||||
|
||||
for (IRepositoryNode repositoryNode : deleteNodes) {
|
||||
refBeans.addAll(checkItemReferenceBeans(factory, deleteActionCache, repositoryNode));
|
||||
}
|
||||
|
||||
return refBeans;
|
||||
}
|
||||
|
||||
protected abstract Set<ItemReferenceBean> checkItemReferenceBeans(IProxyRepositoryFactory factory,
|
||||
DeleteActionCache deleteActionCache, IRepositoryNode currentJobNode);
|
||||
|
||||
protected boolean isItemInDeleteList(ItemReferenceBean bean, boolean isRefer) {
|
||||
if (deleteNodes == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String itemName;
|
||||
String itemVersion;
|
||||
ERepositoryObjectType itemType;
|
||||
for (IRepositoryNode node : deleteNodes) {
|
||||
IRepositoryViewObject repObj = node.getObject();
|
||||
Property property = repObj.getProperty();
|
||||
String label = property.getLabel();
|
||||
String version = property.getVersion();
|
||||
ERepositoryObjectType type = repObj.getRepositoryObjectType();
|
||||
if (isRefer) {
|
||||
itemName = bean.getReferenceItemName();
|
||||
itemVersion = bean.getReferenceItemVersion();
|
||||
itemType = bean.getReferenceItemType();
|
||||
} else {
|
||||
itemName = bean.getItemName();
|
||||
itemVersion = bean.getItemVersion();
|
||||
itemType = bean.getItemType();
|
||||
}
|
||||
if (label.equals(itemName) && version.equals(itemVersion) && type == itemType) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -59,6 +59,7 @@ import org.talend.core.model.properties.RoutineItem;
|
||||
import org.talend.core.model.properties.SQLPatternItem;
|
||||
import org.talend.core.model.repository.ERepositoryObjectType;
|
||||
import org.talend.core.model.repository.Folder;
|
||||
import org.talend.core.model.repository.IRepositoryObject;
|
||||
import org.talend.core.model.repository.IRepositoryViewObject;
|
||||
import org.talend.core.model.repository.LockInfo;
|
||||
import org.talend.core.model.repository.RepositoryViewObject;
|
||||
@@ -874,6 +875,15 @@ public abstract class AbstractEMFRepositoryFactory extends AbstractRepositoryFac
|
||||
|
||||
}
|
||||
|
||||
public void deleteObjectPhysical(Project project, IRepositoryObject objToDelete) throws PersistenceException {
|
||||
if (objToDelete.getRepositoryObjectType() == ERepositoryObjectType.PROCESS
|
||||
|| objToDelete.getRepositoryObjectType() == ERepositoryObjectType.JOBLET) {
|
||||
if (coreSerivce.isAlreadyBuilt(project)) {
|
||||
coreSerivce.removeItemRelations(objToDelete.getProperty().getItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FolderItem getFolderItem(Project project, ERepositoryObjectType itemType, IPath path) {
|
||||
return getFolderHelper(project.getEmfProject()).getFolder(
|
||||
ERepositoryObjectType.getFolderName(itemType) + IPath.SEPARATOR + path);
|
||||
|
||||
@@ -265,6 +265,7 @@ public abstract class AbstractRepositoryFactory implements IRepositoryFactory {
|
||||
public Project[] readProject(boolean unloadResource) throws PersistenceException, BusinessException {
|
||||
return readProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLockStatus() throws PersistenceException {
|
||||
// nothing to do, by default
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
package org.talend.core.repository.model;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.collections.map.MultiKeyMap;
|
||||
import org.eclipse.emf.common.util.EList;
|
||||
import org.talend.commons.exception.PersistenceException;
|
||||
import org.talend.commons.ui.runtime.exception.ExceptionHandler;
|
||||
import org.talend.core.model.general.Project;
|
||||
import org.talend.core.model.process.INode;
|
||||
import org.talend.core.model.process.IProcess2;
|
||||
import org.talend.core.model.properties.Item;
|
||||
import org.talend.core.model.properties.JobletProcessItem;
|
||||
import org.talend.core.model.properties.ProcessItem;
|
||||
import org.talend.core.model.properties.Property;
|
||||
import org.talend.core.model.repository.ERepositoryObjectType;
|
||||
import org.talend.core.model.repository.IRepositoryViewObject;
|
||||
import org.talend.core.repository.ICheckDeleteItemReference;
|
||||
import org.talend.designer.core.model.utils.emf.talendfile.NodeType;
|
||||
import org.talend.repository.ProjectManager;
|
||||
import org.talend.repository.model.ERepositoryStatus;
|
||||
import org.talend.repository.model.IProxyRepositoryFactory;
|
||||
import org.talend.repository.model.IRepositoryNode;
|
||||
import org.talend.repository.model.ItemReferenceBean;
|
||||
import org.talend.repository.ui.actions.DeleteActionCache;
|
||||
|
||||
/**
|
||||
* DOC ycbai class global comment. Detailled comment
|
||||
*/
|
||||
public class CheckJobletDeleteReference extends AbstractCheckDeleteItemReference implements ICheckDeleteItemReference {
|
||||
|
||||
// almost move from the method checkRepositoryNodeFromProcess of DeleteAction class.
|
||||
public Set<ItemReferenceBean> checkItemReferenceBeans(IProxyRepositoryFactory factory, DeleteActionCache deleteActionCache,
|
||||
IRepositoryNode currentJobNode) {
|
||||
IRepositoryViewObject object = currentJobNode.getObject();
|
||||
Item nodeItem = object.getProperty().getItem(); // hywang add
|
||||
boolean needCheckJobletIfUsedInProcess = false;
|
||||
if (nodeItem instanceof JobletProcessItem) {
|
||||
needCheckJobletIfUsedInProcess = true;
|
||||
}
|
||||
Set<ItemReferenceBean> list = new HashSet<ItemReferenceBean>();
|
||||
if (object != null && needCheckJobletIfUsedInProcess) {
|
||||
Property property = object.getProperty();
|
||||
if (property != null) {
|
||||
String label = property.getLabel();
|
||||
String version = property.getVersion();
|
||||
ERepositoryObjectType type = object.getRepositoryObjectType();
|
||||
boolean isItemDeleted = factory.getStatus(object) == ERepositoryStatus.DELETED;
|
||||
Item item = property.getItem();
|
||||
if (!(item instanceof JobletProcessItem)) {
|
||||
return list;
|
||||
}
|
||||
EList nodesList = null;
|
||||
// wzhang added to fix bug 10050
|
||||
Set<Project> refParentProjects = new HashSet<Project>();
|
||||
try {
|
||||
refParentProjects.add(ProjectManager.getInstance().getCurrentProject());
|
||||
refParentProjects.addAll(ProjectManager.getInstance().getReferencedProjects());
|
||||
for (Project refP : refParentProjects) {
|
||||
List<IRepositoryViewObject> processes = factory.getAll(refP, ERepositoryObjectType.PROCESS, true);
|
||||
List<IRepositoryViewObject> jobletes = factory.getAll(refP, ERepositoryObjectType.JOBLET, true);
|
||||
processes.addAll(jobletes);
|
||||
deleteActionCache.setProcessList(processes);
|
||||
for (IRepositoryViewObject process : deleteActionCache.getProcessList()) {
|
||||
Property property2 = process.getProperty();
|
||||
boolean isDelete = factory.getStatus(process) == ERepositoryStatus.DELETED;
|
||||
Item item2 = property2.getItem();
|
||||
if (item == item2) {
|
||||
continue;
|
||||
}
|
||||
if (!isOpenedItem(item2, deleteActionCache.getOpenProcessMap())) {
|
||||
if (item2 instanceof ProcessItem) {
|
||||
nodesList = ((ProcessItem) item2).getProcess().getNode();
|
||||
} else if (item2 instanceof JobletProcessItem) {
|
||||
nodesList = ((JobletProcessItem) item2).getJobletProcess().getNode();
|
||||
}
|
||||
}
|
||||
if (nodesList != null) {
|
||||
for (Object object2 : nodesList) {
|
||||
if (object2 instanceof NodeType) {
|
||||
NodeType nodeType = (NodeType) object2;
|
||||
nodeType.getElementParameter();
|
||||
boolean equals = nodeType.getComponentName().equals(label);
|
||||
if (equals) {
|
||||
String path = item2.getState().getPath();
|
||||
boolean found = false;
|
||||
ItemReferenceBean bean = new ItemReferenceBean();
|
||||
bean.setItemName(label);
|
||||
bean.setItemVersion(version);
|
||||
bean.setItemType(type);
|
||||
bean.setItemDeleted(isItemDeleted);
|
||||
bean.setReferenceItemName(property2.getLabel());
|
||||
bean.setReferenceItemVersion(property2.getVersion());
|
||||
bean.setReferenceItemType(process.getRepositoryObjectType());
|
||||
bean.setReferenceItemPath(path);
|
||||
bean.setReferenceProjectName(refP.getLabel());
|
||||
bean.setReferenceItemDeleted(isDelete);
|
||||
for (ItemReferenceBean b : list) {
|
||||
if (b.equals(bean)) {
|
||||
found = true;
|
||||
b.addNodeNum();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
list.add(bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (IProcess2 openedProcess : deleteActionCache.getOpenedProcessList()) {
|
||||
for (INode node : openedProcess.getGraphicalNodes()) {
|
||||
boolean equals = node.getComponent().getName().equals(label);
|
||||
boolean isDelete = factory.getStatus(openedProcess) == ERepositoryStatus.DELETED;
|
||||
Property property2 = openedProcess.getProperty();
|
||||
Item item2 = property2.getItem();
|
||||
String path = item2.getState().getPath();
|
||||
if (equals) {
|
||||
boolean found = false;
|
||||
ItemReferenceBean bean = new ItemReferenceBean();
|
||||
bean.setItemName(label);
|
||||
bean.setItemVersion(version);
|
||||
bean.setItemType(type);
|
||||
bean.setItemDeleted(isItemDeleted);
|
||||
bean.setReferenceItemName(property2.getLabel());
|
||||
bean.setReferenceItemVersion(property2.getVersion());
|
||||
bean.setReferenceItemType(ERepositoryObjectType.getItemType(item2));
|
||||
bean.setReferenceItemPath(path);
|
||||
bean.setReferenceProjectName(refP.getLabel());
|
||||
bean.setReferenceItemDeleted(isDelete);
|
||||
for (ItemReferenceBean b : list) {
|
||||
if (b.equals(bean)) {
|
||||
found = true;
|
||||
b.addNodeNum();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
list.add(bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (PersistenceException e) {
|
||||
ExceptionHandler.process(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the reference job or joblet is in the recycle bin but the joblet is not then no need to check; If both the
|
||||
* joblet and the reference job or joblet are all in the recycle bin and they are all in the delete list then no
|
||||
* need to check them; If both the joblet and the reference job or joblet are all not in the recycle bin and
|
||||
* they are all in the delete list then no need to check them too.
|
||||
*/
|
||||
Iterator<ItemReferenceBean> it = list.iterator();
|
||||
while (it.hasNext()) {
|
||||
ItemReferenceBean bean = it.next();
|
||||
if ((!bean.isItemDeleted() && bean.isReferenceItemDeleted())
|
||||
|| (bean.isItemDeleted() && bean.isReferenceItemDeleted() && isItemInDeleteList(bean, true))
|
||||
|| (!bean.isItemDeleted() && !bean.isReferenceItemDeleted() && isItemInDeleteList(bean, true))) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static boolean isOpenedItem(Item openedItem, MultiKeyMap openProcessMap) {
|
||||
if (openedItem == null) {
|
||||
return false;
|
||||
}
|
||||
Property property = openedItem.getProperty();
|
||||
return (openProcessMap.get(property.getId(), property.getLabel(), property.getVersion()) != null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -470,7 +470,9 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
checkFileNameAndPath(project, label, RepositoryConstants.FOLDER_PATTERN, type, path, true);
|
||||
}
|
||||
Folder createFolder = this.repositoryFactoryFromProvider.createFolder(project, type, path, label, isImportItem);
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.FOLDER_CREATE.getName(), path, new Object[] { createFolder, type });
|
||||
if (type == ERepositoryObjectType.PROCESS || type == ERepositoryObjectType.JOBLET) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.FOLDER_CREATE.getName(), path, new Object[] { createFolder, type });
|
||||
}
|
||||
return createFolder;
|
||||
}
|
||||
|
||||
@@ -493,9 +495,6 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
@Override
|
||||
public synchronized void deleteFolder(Project project, ERepositoryObjectType type, IPath path, boolean fromEmptyRecycleBin)
|
||||
throws PersistenceException {
|
||||
if (hasLockedItems(type, path)) {
|
||||
throw new PersistenceException("Cannot delete a folder which contains locked items");
|
||||
}
|
||||
this.repositoryFactoryFromProvider.deleteFolder(project, type, path, fromEmptyRecycleBin);
|
||||
if (type == ERepositoryObjectType.PROCESS) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.FOLDER_DELETE.getName(), path, type);
|
||||
@@ -505,21 +504,6 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasLockedItems(ERepositoryObjectType type, IPath path) throws PersistenceException {
|
||||
if (ERepositoryObjectType.COMPONENTS.equals(type)) {
|
||||
return false;
|
||||
}
|
||||
Project baseProject = getRepositoryContext().getProject();
|
||||
List<IRepositoryViewObject> objects = this.repositoryFactoryFromProvider.getMetadataByFolder(baseProject, type, path);
|
||||
for (IRepositoryViewObject repositoryObject : objects) {
|
||||
if (getStatus(repositoryObject.getProperty().getItem()) == ERepositoryStatus.LOCK_BY_USER
|
||||
|| getStatus(repositoryObject.getProperty().getItem()) == ERepositoryStatus.LOCK_BY_OTHER) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -529,9 +513,6 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
*/
|
||||
@Override
|
||||
public void moveFolder(ERepositoryObjectType type, IPath sourcePath, IPath targetPath) throws PersistenceException {
|
||||
if (hasLockedItems(type, sourcePath)) {
|
||||
throw new PersistenceException("Cannot move a folder which contains locked items");
|
||||
}
|
||||
this.repositoryFactoryFromProvider.moveFolder(type, sourcePath, targetPath);
|
||||
if (type == ERepositoryObjectType.PROCESS) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.FOLDER_MOVE.getName(), sourcePath, targetPath);
|
||||
@@ -600,9 +581,13 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
*/
|
||||
@Override
|
||||
public void renameFolder(ERepositoryObjectType type, IPath path, String label) throws PersistenceException {
|
||||
if (hasLockedItems(type, path)) {
|
||||
throw new PersistenceException("Cannot rename a folder which contains locked items");
|
||||
}
|
||||
// if (path.lastSegment().equalsIgnoreCase(label)) {
|
||||
// not supported to rename directly to another case.
|
||||
// actually only possible way without it, would be to move to another temp folder, then rename again.
|
||||
// (means 2 commits)
|
||||
// to simplify for now, we don't allow to rename one folder to another case.
|
||||
// return;
|
||||
// }
|
||||
this.repositoryFactoryFromProvider.renameFolder(type, path, label);
|
||||
if (type == ERepositoryObjectType.PROCESS) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.FOLDER_RENAME.getName(), path, label);
|
||||
@@ -613,6 +598,12 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
this.repositoryFactoryFromProvider.updateItemsPath(type, path.removeLastSegments(1).append(label));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.talend.repository.model.IRepositoryFactory#deleteObject(org.talend.core.model.general.Project,
|
||||
* org.talend.core.model.repository.IRepositoryViewObject)
|
||||
*/
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -636,8 +627,25 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
// log.debug("Logical deletion [" + objToDelete + "] by " + getRepositoryContext().getUser() + ".");
|
||||
String str[] = new String[] { object + "", getRepositoryContext().getUser() + "" };//$NON-NLS-1$ //$NON-NLS-2$
|
||||
log.debug(Messages.getString("ProxyRepositoryFactory.log.logicalDeletion", str)); //$NON-NLS-1$
|
||||
boolean isExtendPoint = false;
|
||||
ERepositoryObjectType repositoryObjectType = object.getRepositoryObjectType();
|
||||
for (IRepositoryContentHandler handler : RepositoryContentManager.getHandlers()) {
|
||||
isExtendPoint = handler.isRepObjType(repositoryObjectType);
|
||||
if (isExtendPoint == true) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO this need to be refactered after M2.
|
||||
if (isExtendPoint || object.getRepositoryObjectType() == ERepositoryObjectType.PROCESS
|
||||
|| object.getRepositoryObjectType() == ERepositoryObjectType.JOBLET
|
||||
|| object.getRepositoryObjectType() == ERepositoryObjectType.ROUTINES
|
||||
|| object.getRepositoryObjectType() == ERepositoryObjectType.JOB_SCRIPT) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_DELETE_TO_RECYCLE_BIN.getName(), null, object);
|
||||
}
|
||||
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.DELETE_TO_RECYCLE_BIN.getName(), null, object);
|
||||
if (objToDelete.getRepositoryObjectType() == ERepositoryObjectType.BUSINESS_PROCESS) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.BUSINESS_DELETE_TO_RECYCLE_BIN.getName(), null, object);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -692,13 +700,12 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
IRepositoryViewObject object = new RepositoryObject(objToDelete.getProperty());
|
||||
boolean isExtendPoint = false;
|
||||
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.DELETE_FOREVER.getName(), null, object);
|
||||
|
||||
ERepositoryObjectType repositoryObjectType = object.getRepositoryObjectType();
|
||||
for (IRepositoryContentHandler handler : RepositoryContentManager.getHandlers()) {
|
||||
isExtendPoint = handler.isRepObjType(repositoryObjectType);
|
||||
if (isExtendPoint == true) {
|
||||
if (repositoryObjectType == handler.getProcessType()) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_DELETE_FOREVER.getName(), null, object);
|
||||
coreService.removeJobLaunch(object);
|
||||
}
|
||||
if (repositoryObjectType == handler.getCodeType()) {
|
||||
@@ -711,17 +718,24 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (repositoryObjectType == ERepositoryObjectType.PROCESS) {
|
||||
// delete the job launch, for bug 8878
|
||||
coreService.removeJobLaunch(object);
|
||||
}
|
||||
|
||||
if (repositoryObjectType == ERepositoryObjectType.ROUTINES) {
|
||||
try {
|
||||
coreService.deleteRoutinefile(object);
|
||||
} catch (Exception e) {
|
||||
ExceptionHandler.process(e);
|
||||
if (repositoryObjectType == ERepositoryObjectType.PROCESS || repositoryObjectType == ERepositoryObjectType.JOBLET
|
||||
|| repositoryObjectType == ERepositoryObjectType.ROUTINES) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_DELETE_FOREVER.getName(), null, object);
|
||||
if (repositoryObjectType == ERepositoryObjectType.PROCESS) {
|
||||
// delete the job launch, for bug 8878
|
||||
coreService.removeJobLaunch(object);
|
||||
}
|
||||
|
||||
if (repositoryObjectType == ERepositoryObjectType.ROUTINES) {
|
||||
try {
|
||||
coreService.deleteRoutinefile(object);
|
||||
} catch (Exception e) {
|
||||
ExceptionHandler.process(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (repositoryObjectType == ERepositoryObjectType.BUSINESS_PROCESS) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.BUSINESS_DELETE_FOREVER.getName(), null, object);
|
||||
}
|
||||
|
||||
if (repositoryObjectType == ERepositoryObjectType.PROCESS) {
|
||||
@@ -766,7 +780,11 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
break;
|
||||
}
|
||||
}
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.RESTORE.getName(), null, objToRestore);
|
||||
if (isExtendPoint || objToRestore.getRepositoryObjectType() == ERepositoryObjectType.PROCESS
|
||||
|| objToRestore.getRepositoryObjectType() == ERepositoryObjectType.JOBLET
|
||||
|| objToRestore.getRepositoryObjectType() == ERepositoryObjectType.ROUTINES) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_RESTORE.getName(), null, objToRestore);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -799,10 +817,19 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
log.debug(Messages.getString("ProxyRepositoryFactory.log.move", str)); //$NON-NLS-1$
|
||||
// unlock(getItem(objToMove));
|
||||
|
||||
if (sourcePath != null && sourcePath.length == 1) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.MOVE.getName(), objToMove,
|
||||
new IPath[] { sourcePath[0], targetPath });
|
||||
if (objToMove.getRepositoryObjectType() == ERepositoryObjectType.PROCESS) {
|
||||
if (sourcePath != null && sourcePath.length == 1) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_MOVE.getName(), objToMove, new IPath[] { sourcePath[0],
|
||||
targetPath });
|
||||
}
|
||||
}
|
||||
if (objToMove.getRepositoryObjectType() == ERepositoryObjectType.JOBLET) {
|
||||
if (sourcePath != null && sourcePath.length == 1) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOBLET_MOVE.getName(), objToMove, new IPath[] { sourcePath[0],
|
||||
targetPath });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO SML Renommer et finir la m<>thode et la plugger dans toutes les m<>thodes
|
||||
@@ -833,18 +860,18 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
// getStatus(item)
|
||||
if (getStatus(item).isPotentiallyEditable()) {
|
||||
this.repositoryFactoryFromProvider.lock(item);
|
||||
// TDI-21187 Lock a job with doc, on TAC side both job and documentation are locked.
|
||||
// if ((item instanceof JobletProcessItem || item instanceof ProcessItem)
|
||||
// && getStatus(item) == ERepositoryStatus.LOCK_BY_USER) {
|
||||
// String docId = item.getProperty().getId() + "doc";
|
||||
// IRepositoryViewObject repositoryViewObject = this.repositoryFactoryFromProvider.getLastVersion(
|
||||
// projectManager.getCurrentProject(), docId);
|
||||
// if (repositoryViewObject != null) {
|
||||
// Property property = repositoryViewObject.getProperty();
|
||||
// Item documentationItem = property.getItem();
|
||||
// this.repositoryFactoryFromProvider.lock(documentationItem);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
if ((item instanceof JobletProcessItem || item instanceof ProcessItem)
|
||||
&& getStatus(item) == ERepositoryStatus.LOCK_BY_USER) {
|
||||
String docId = item.getProperty().getId() + "doc";
|
||||
IRepositoryViewObject repositoryViewObject = this.repositoryFactoryFromProvider.getLastVersion(
|
||||
projectManager.getCurrentProject(), docId);
|
||||
if (repositoryViewObject != null) {
|
||||
Property property = repositoryViewObject.getProperty();
|
||||
Item documentationItem = property.getItem();
|
||||
this.repositoryFactoryFromProvider.lock(documentationItem);
|
||||
}
|
||||
}
|
||||
notifyLock(item, true);
|
||||
// i18n
|
||||
// log.debug("Lock [" + item + "] by \"" + getRepositoryContext().getUser() + "\".");
|
||||
@@ -1204,9 +1231,8 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
isImportItem);
|
||||
|
||||
this.repositoryFactoryFromProvider.create(project, item, path, isImportItem);
|
||||
if (isImportItem.length == 0) {
|
||||
// no listener if from import, or it will be too slow.
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.CREATE.getName(), null, item);
|
||||
if ((item instanceof ProcessItem || item instanceof JobletProcessItem) && (isImportItem.length == 0)) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_CREATE.getName(), null, item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1223,8 +1249,9 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
@Override
|
||||
public void save(Project project, Item item, boolean... isMigrationTask) throws PersistenceException {
|
||||
this.repositoryFactoryFromProvider.save(project, item);
|
||||
if (isMigrationTask == null || isMigrationTask.length == 0) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.SAVE.getName(), null, item);
|
||||
if ((item instanceof ProcessItem || item instanceof JobletProcessItem)
|
||||
&& (isMigrationTask == null || isMigrationTask.length == 0)) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_SAVE.getName(), null, item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1241,7 +1268,9 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
@Override
|
||||
public void save(Project project, Property property, String... originalNameAndVersion) throws PersistenceException {
|
||||
this.repositoryFactoryFromProvider.save(project, property);
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.PROPERTIES_CHANGE.getName(), originalNameAndVersion, property);
|
||||
if (property.getItem() instanceof ProcessItem || property.getItem() instanceof JobletProcessItem) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_PROPERTIES_CHANGE.getName(), originalNameAndVersion, property);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1264,7 +1293,9 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
|
||||
Item targetItem = this.repositoryFactoryFromProvider.copy(sourceItem, targetPath);
|
||||
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.COPY.getName(), sourceItem, targetItem);
|
||||
if (sourceItem instanceof ProcessItem || sourceItem instanceof JobletProcessItem) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_COPY.getName(), sourceItem, targetItem);
|
||||
}
|
||||
return targetItem;
|
||||
|
||||
}
|
||||
@@ -1292,7 +1323,7 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
|
||||
@Override
|
||||
public void saveCopy(Item sourceItem, Item targetItem) {
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.COPY.getName(), sourceItem, targetItem);
|
||||
fireRepositoryPropertyChange(ERepositoryActionName.JOB_COPY.getName(), sourceItem, targetItem);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1340,17 +1371,17 @@ public final class ProxyRepositoryFactory implements IProxyRepositoryFactory {
|
||||
Date modificationDate = obj.getProperty().getModificationDate();
|
||||
if (modificationDate == null || commitDate == null || modificationDate.before(commitDate)) {
|
||||
this.repositoryFactoryFromProvider.unlock(obj);
|
||||
// TDI-21187 Lock a job with doc, on TAC side both job and documentation are locked.
|
||||
// if (obj instanceof JobletProcessItem || obj instanceof ProcessItem) {
|
||||
// String docId = obj.getProperty().getId() + "doc";
|
||||
// IRepositoryViewObject repositoryViewObject = this.repositoryFactoryFromProvider.getLastVersion(
|
||||
// projectManager.getCurrentProject(), docId);
|
||||
// if (repositoryViewObject != null) {
|
||||
// Property property = repositoryViewObject.getProperty();
|
||||
// Item documentationItem = property.getItem();
|
||||
// this.repositoryFactoryFromProvider.unlock(documentationItem);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
if (obj instanceof JobletProcessItem || obj instanceof ProcessItem) {
|
||||
String docId = obj.getProperty().getId() + "doc";
|
||||
IRepositoryViewObject repositoryViewObject = this.repositoryFactoryFromProvider.getLastVersion(
|
||||
projectManager.getCurrentProject(), docId);
|
||||
if (repositoryViewObject != null) {
|
||||
Property property = repositoryViewObject.getProperty();
|
||||
Item documentationItem = property.getItem();
|
||||
this.repositoryFactoryFromProvider.unlock(documentationItem);
|
||||
}
|
||||
}
|
||||
notifyLock(obj, false);
|
||||
// i18n
|
||||
// log.debug("Unlock [" + obj + "] by \"" + getRepositoryContext().getUser() + "\".");
|
||||
|
||||
@@ -4,8 +4,6 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import org.talend.core.model.properties.Item;
|
||||
import org.talend.core.model.properties.JobletProcessItem;
|
||||
import org.talend.core.model.properties.ProcessItem;
|
||||
import org.talend.repository.documentation.ERepositoryActionName;
|
||||
|
||||
/**
|
||||
@@ -14,14 +12,13 @@ import org.talend.repository.documentation.ERepositoryActionName;
|
||||
*/
|
||||
public abstract class AbstractJobCreateListener implements PropertyChangeListener {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent event) {
|
||||
|
||||
if (!event.getPropertyName().equals(ERepositoryActionName.CREATE.getName())) {
|
||||
if (!event.getPropertyName().equals(ERepositoryActionName.JOB_CREATE.getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event.getNewValue() instanceof ProcessItem) && !(event.getNewValue() instanceof JobletProcessItem)) {
|
||||
if (!(event.getNewValue() instanceof Item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user