79 |
79 |
* Results counter to create unique ids.
|
80 |
80 |
*/
|
81 |
81 |
private static int next = 0;
|
82 |
|
|
|
82 |
|
83 |
83 |
/**
|
84 |
84 |
* Editor can use this to test if the result has been computed once.
|
85 |
85 |
*/
|
... | ... | |
95 |
95 |
* like after updating parameters
|
96 |
96 |
*/
|
97 |
97 |
protected boolean dirty = true;
|
98 |
|
|
|
98 |
|
99 |
99 |
/**
|
100 |
100 |
* if a method changed the internal data without **recomputing** the result, the result must be marked "altered"
|
101 |
101 |
*/
|
... | ... | |
137 |
137 |
* Also permits to optimize computing by testing if a specific parameter value has changed since last computing and skip or not some computing steps.
|
138 |
138 |
*/
|
139 |
139 |
protected ArrayList<HashMap<String, Object>> parametersHistory = new ArrayList<HashMap<String, Object>>();
|
140 |
|
|
|
140 |
|
141 |
141 |
/**
|
142 |
142 |
* Internal persistable state.
|
143 |
143 |
*/
|
... | ... | |
179 |
179 |
*/
|
180 |
180 |
@Parameter(key=TXMPreferences.CREATION_DATE, type=Parameter.INTERNAL)
|
181 |
181 |
private Date creationDate;
|
182 |
|
|
|
182 |
|
183 |
183 |
/**
|
184 |
184 |
* If locked, the result is not updated when computed.
|
185 |
185 |
*/
|
186 |
186 |
@Parameter(key=TXMPreferences.LOCK, type=Parameter.INTERNAL)
|
187 |
|
protected boolean locked = false;
|
188 |
|
|
|
187 |
protected Boolean locked = false;
|
|
188 |
|
189 |
189 |
/**
|
190 |
190 |
* Current computing state.
|
191 |
191 |
* True if the result is in the process of computing (is in compute(,) method)
|
... | ... | |
226 |
226 |
}
|
227 |
227 |
|
228 |
228 |
// no parametersNodePath -> new result
|
229 |
|
|
|
229 |
|
230 |
230 |
if (parametersNodePath == null) { // new object
|
231 |
231 |
if (this.getProject() != null) {
|
232 |
232 |
parametersNodePath = this.getProject().getParametersNodeRootPath();
|
... | ... | |
234 |
234 |
else {
|
235 |
235 |
parametersNodePath = ""; //$NON-NLS-1$;
|
236 |
236 |
}
|
237 |
|
|
|
237 |
|
238 |
238 |
this.parametersNodePath = parametersNodePath + createUUID() + "_" + this.getClass().getSimpleName(); //$NON-NLS-1$;
|
239 |
239 |
}
|
240 |
240 |
else {
|
... | ... | |
265 |
265 |
parent == null &&
|
266 |
266 |
this.parametersNodePath != null &&
|
267 |
267 |
!parentNodePath.isEmpty()) {
|
268 |
|
|
|
268 |
|
269 |
269 |
Log.finest("Searching parent with UUID " + parentNodePath + "..."); //$NON-NLS-1$ //$NON-NLS-2$
|
270 |
|
|
|
270 |
|
271 |
271 |
//TODO this is quite CPU expensive because 'retrievedParent' is researched in all projects
|
272 |
272 |
TXMResult retrievedParent = TXMResult.getResult(parentNodePath);
|
273 |
273 |
if (retrievedParent != null) {
|
... | ... | |
280 |
280 |
TBXPreferences.delete(this);
|
281 |
281 |
}
|
282 |
282 |
catch(Exception e) {
|
283 |
|
|
|
283 |
|
284 |
284 |
}
|
285 |
285 |
return;
|
286 |
286 |
}
|
... | ... | |
290 |
290 |
try {
|
291 |
291 |
this.autoLoadParametersFromAnnotations(); // auto fill from Parameter annotations
|
292 |
292 |
this.loadParameters(); // subclasses manual settings
|
293 |
|
|
|
293 |
|
294 |
294 |
try {
|
295 |
295 |
if (creationDate == null) {
|
296 |
296 |
creationDate = Calendar.getInstance().getTime();
|
... | ... | |
325 |
325 |
public boolean isAltered() {
|
326 |
326 |
return altered;
|
327 |
327 |
}
|
328 |
|
|
|
328 |
|
329 |
329 |
/**
|
330 |
330 |
* Mark the result as altered -> modifications are lost after a re-compute
|
331 |
331 |
*/
|
332 |
332 |
public void setAltered() {
|
333 |
333 |
this.altered = true;
|
334 |
334 |
}
|
335 |
|
|
|
335 |
|
336 |
336 |
/**
|
|
337 |
* Do something when project is closed
|
|
338 |
*/
|
|
339 |
public void onProjectClose() {
|
|
340 |
|
|
341 |
}
|
|
342 |
|
|
343 |
/**
|
|
344 |
* Do something when project is opened
|
|
345 |
*/
|
|
346 |
public void onProjectOpen() {
|
|
347 |
|
|
348 |
}
|
|
349 |
|
|
350 |
/**
|
337 |
351 |
* Locks/unlocks the result.
|
338 |
352 |
*/
|
339 |
353 |
public void setLocked(boolean state) {
|
340 |
354 |
this.locked = state;
|
341 |
|
|
|
355 |
|
342 |
356 |
if (this.locked && this.parent != null) {
|
343 |
357 |
this.parent.setLocked(true);
|
344 |
358 |
}
|
... | ... | |
348 |
362 |
}
|
349 |
363 |
}
|
350 |
364 |
}
|
351 |
|
|
|
365 |
|
352 |
366 |
/**
|
353 |
367 |
* @return true if the result is locked
|
354 |
368 |
*/
|
355 |
369 |
public boolean isLocked() {
|
356 |
370 |
return this.locked;
|
357 |
371 |
}
|
358 |
|
|
|
372 |
|
359 |
373 |
/**
|
360 |
374 |
* Creates an UUID dedicated to persistence of this result.
|
361 |
375 |
* @return
|
... | ... | |
365 |
379 |
//this.uniqueID = this.getClass().getName() + '@' + ID_TIME_FORMAT.format(new Date(System.currentTimeMillis())) + "_" + UUID.randomUUID();
|
366 |
380 |
return UUID_PREFIX + ID_TIME_FORMAT.format(new Date(System.currentTimeMillis())) + "_" + nextInt();
|
367 |
381 |
}
|
368 |
|
|
|
382 |
|
369 |
383 |
/**
|
370 |
384 |
*
|
371 |
385 |
* @return the next integer in the current session of TXM
|
... | ... | |
557 |
571 |
}
|
558 |
572 |
}
|
559 |
573 |
|
560 |
|
|
|
574 |
|
561 |
575 |
try {
|
562 |
576 |
if(this.getLastParametersFromHistory().isEmpty()) {
|
563 |
577 |
this.parametersHistory.remove(this.parametersHistory.size() - 1);
|
... | ... | |
586 |
600 |
* @return
|
587 |
601 |
*/
|
588 |
602 |
public boolean hasParameterChanged(String key, HashMap<String, Object> lastParameters) {
|
589 |
|
|
|
603 |
|
590 |
604 |
if(lastParameters == null) {
|
591 |
605 |
return true;
|
592 |
606 |
}
|
593 |
|
|
|
607 |
|
594 |
608 |
if (key.isEmpty()) {
|
595 |
609 |
return false;
|
596 |
610 |
}
|
... | ... | |
624 |
638 |
}
|
625 |
639 |
|
626 |
640 |
boolean hasParameterChanged = false;
|
627 |
|
|
|
641 |
|
628 |
642 |
List<Field> fields = this.getAllFields();
|
629 |
|
|
|
643 |
|
630 |
644 |
for (Field f : fields) {
|
631 |
645 |
Parameter parameter = f.getAnnotation(Parameter.class);
|
632 |
646 |
if (parameter == null || parameter.type() != parameterType) {
|
... | ... | |
643 |
657 |
f.setAccessible(true); // to be able to test the field values
|
644 |
658 |
|
645 |
659 |
hasParameterChanged = this.hasParameterChanged(name, lastParameters);
|
646 |
|
|
|
660 |
|
647 |
661 |
if (hasParameterChanged) {
|
648 |
662 |
Log.finest("TXMResult.hasParameterChanged(): " + this.getClass().getSimpleName() + ": parameter " + name + " has changed.");
|
649 |
663 |
break;
|
650 |
664 |
}
|
651 |
665 |
}
|
652 |
|
|
|
666 |
|
653 |
667 |
return hasParameterChanged;
|
654 |
668 |
}
|
655 |
669 |
|
656 |
|
|
|
670 |
|
657 |
671 |
/**
|
658 |
672 |
* Checks if at least one computing parameter value has changed since last computing.
|
659 |
673 |
* @return
|
... | ... | |
662 |
676 |
public boolean hasParameterChanged() throws Exception {
|
663 |
677 |
return this.hasParameterChanged(this.getLastParametersFromHistory(), Parameter.COMPUTING);
|
664 |
678 |
}
|
665 |
|
|
666 |
|
|
|
679 |
|
|
680 |
|
667 |
681 |
/**
|
668 |
682 |
* Dumps the command and default preferences of the result preferences node qualifier.
|
669 |
683 |
* @return
|
... | ... | |
746 |
760 |
|
747 |
761 |
|
748 |
762 |
|
749 |
|
// /**
|
750 |
|
// * Updates the dirty state by comparing an old parameter with a new one.
|
751 |
|
// *
|
752 |
|
// * @param lastValue may be null
|
753 |
|
// * @param newValue may be null
|
754 |
|
// */
|
755 |
|
// protected void updateDirty(Object lastValue, Object newValue) {
|
756 |
|
// if(lastValue == null && newValue == null) {
|
757 |
|
// return;
|
758 |
|
// }
|
759 |
|
// if (lastValue == null || !lastValue.equals(newValue)) {
|
760 |
|
// Log.info("TXMResult.updateDirty(): " + this.getClass().getSimpleName() + ": setting dirty to true: last = "+ lastValue + " / new = " + newValue);
|
761 |
|
// this.setDirty();
|
762 |
|
// }
|
763 |
|
// }
|
|
763 |
// /**
|
|
764 |
// * Updates the dirty state by comparing an old parameter with a new one.
|
|
765 |
// *
|
|
766 |
// * @param lastValue may be null
|
|
767 |
// * @param newValue may be null
|
|
768 |
// */
|
|
769 |
// protected void updateDirty(Object lastValue, Object newValue) {
|
|
770 |
// if(lastValue == null && newValue == null) {
|
|
771 |
// return;
|
|
772 |
// }
|
|
773 |
// if (lastValue == null || !lastValue.equals(newValue)) {
|
|
774 |
// Log.info("TXMResult.updateDirty(): " + this.getClass().getSimpleName() + ": setting dirty to true: last = "+ lastValue + " / new = " + newValue);
|
|
775 |
// this.setDirty();
|
|
776 |
// }
|
|
777 |
// }
|
764 |
778 |
|
765 |
779 |
/**
|
766 |
780 |
* Sets the dirty state to true if a parameter has changed since last computing.
|
... | ... | |
768 |
782 |
* @throws Exception
|
769 |
783 |
*/
|
770 |
784 |
public void updateDirtyFromHistory() throws Exception {
|
771 |
|
//
|
772 |
|
//// // result has never been computed
|
773 |
|
//// if(this.getLastParametersFromHistory() == null) {
|
774 |
|
//// this.dirty = true;
|
775 |
|
//// return true;
|
776 |
|
//// }
|
777 |
|
////
|
778 |
|
//// List<Field> fields = this.getAllFields();
|
779 |
|
////
|
780 |
|
//// for (Field f : fields) {
|
781 |
|
//// Parameter parameter = f.getAnnotation(Parameter.class);
|
782 |
|
//// if (parameter == null
|
783 |
|
//// || parameter.type() == Parameter.INTERNAL
|
784 |
|
//// //|| parameter.type() != Parameter.COMPUTING
|
785 |
|
//// ) {
|
786 |
|
//// continue;
|
787 |
|
//// }
|
788 |
|
//// String name;
|
789 |
|
//// if (!parameter.key().isEmpty()) {
|
790 |
|
//// name = parameter.key();
|
791 |
|
//// }
|
792 |
|
//// else {
|
793 |
|
//// name = f.getName();
|
794 |
|
//// }
|
795 |
|
////
|
796 |
|
//// f.setAccessible(true); // to be able to test the field values
|
797 |
|
////
|
798 |
|
//// Object previousValue = this.getLastParametersFromHistory().get(name);
|
799 |
|
//// Object newValue = f.get(this);
|
800 |
|
////
|
801 |
|
//// // // FIXME: debug
|
802 |
|
//// // Log.finest("TXMResult.isDirtyFromHistory(): checking parameter: " + name);
|
803 |
|
////
|
804 |
|
//// this.updateDirty(previousValue, newValue);
|
805 |
|
//// if (this.dirty) {
|
806 |
|
//// Log.finest("TXMResult.isDirtyFromHistory(): " + this.getClass().getSimpleName() + ": parameter " + name + " has changed.");
|
807 |
|
//// return this.dirty; // no need to go further
|
808 |
|
//// }
|
809 |
|
//// }
|
810 |
|
//// return this.dirty;
|
811 |
|
//
|
812 |
|
// this.dirty = this.hasParameterChanged();
|
813 |
|
//// if (this.chartDirty) {
|
814 |
|
//// // FIXME: debug
|
815 |
|
//// Log.finest("ChartResult.isChartDirtyFromHistory(): parameter " + name + " has changed.");
|
816 |
|
//// return this.chartDirty; // no need to go further
|
817 |
|
//// }
|
818 |
|
//// return this.dirty;
|
819 |
|
// if(this.dirty) {
|
820 |
|
// return true;
|
821 |
|
// }
|
822 |
|
// else {
|
823 |
|
//return this.hasParameterChanged();
|
824 |
|
// }
|
825 |
|
|
|
785 |
//
|
|
786 |
//// // result has never been computed
|
|
787 |
//// if(this.getLastParametersFromHistory() == null) {
|
|
788 |
//// this.dirty = true;
|
|
789 |
//// return true;
|
|
790 |
//// }
|
|
791 |
////
|
|
792 |
//// List<Field> fields = this.getAllFields();
|
|
793 |
////
|
|
794 |
//// for (Field f : fields) {
|
|
795 |
//// Parameter parameter = f.getAnnotation(Parameter.class);
|
|
796 |
//// if (parameter == null
|
|
797 |
//// || parameter.type() == Parameter.INTERNAL
|
|
798 |
//// //|| parameter.type() != Parameter.COMPUTING
|
|
799 |
//// ) {
|
|
800 |
//// continue;
|
|
801 |
//// }
|
|
802 |
//// String name;
|
|
803 |
//// if (!parameter.key().isEmpty()) {
|
|
804 |
//// name = parameter.key();
|
|
805 |
//// }
|
|
806 |
//// else {
|
|
807 |
//// name = f.getName();
|
|
808 |
//// }
|
|
809 |
////
|
|
810 |
//// f.setAccessible(true); // to be able to test the field values
|
|
811 |
////
|
|
812 |
//// Object previousValue = this.getLastParametersFromHistory().get(name);
|
|
813 |
//// Object newValue = f.get(this);
|
|
814 |
////
|
|
815 |
//// // // FIXME: debug
|
|
816 |
//// // Log.finest("TXMResult.isDirtyFromHistory(): checking parameter: " + name);
|
|
817 |
////
|
|
818 |
//// this.updateDirty(previousValue, newValue);
|
|
819 |
//// if (this.dirty) {
|
|
820 |
//// Log.finest("TXMResult.isDirtyFromHistory(): " + this.getClass().getSimpleName() + ": parameter " + name + " has changed.");
|
|
821 |
//// return this.dirty; // no need to go further
|
|
822 |
//// }
|
|
823 |
//// }
|
|
824 |
//// return this.dirty;
|
|
825 |
//
|
|
826 |
// this.dirty = this.hasParameterChanged();
|
|
827 |
//// if (this.chartDirty) {
|
|
828 |
//// // FIXME: debug
|
|
829 |
//// Log.finest("ChartResult.isChartDirtyFromHistory(): parameter " + name + " has changed.");
|
|
830 |
//// return this.chartDirty; // no need to go further
|
|
831 |
//// }
|
|
832 |
//// return this.dirty;
|
|
833 |
// if(this.dirty) {
|
|
834 |
// return true;
|
|
835 |
// }
|
|
836 |
// else {
|
|
837 |
//return this.hasParameterChanged();
|
|
838 |
// }
|
|
839 |
|
826 |
840 |
if(this.hasParameterChanged()) {
|
827 |
841 |
this.dirty = true;
|
828 |
842 |
}
|
829 |
|
|
|
843 |
|
830 |
844 |
}
|
831 |
845 |
|
832 |
846 |
|
... | ... | |
867 |
881 |
* @param dirty
|
868 |
882 |
*/
|
869 |
883 |
public void setDirty(boolean dirty) {
|
|
884 |
setDirty(dirty, true);
|
|
885 |
}
|
|
886 |
|
|
887 |
/**
|
|
888 |
* Sets the result dirty state so editors or others will know the TXMResult needs to be recomputed or not.
|
|
889 |
* This method is also recursively called on all the children branch sets the new dirty state.
|
|
890 |
* @param dirty
|
|
891 |
*/
|
|
892 |
public void setDirty(boolean dirty, boolean propagate) {
|
870 |
893 |
this.dirty = dirty;
|
871 |
|
for (int i = 0; i < this.children.size(); i++) {
|
872 |
|
this.children.get(i).setDirty(dirty);
|
|
894 |
if (propagate) {
|
|
895 |
for (int i = 0; i < this.children.size(); i++) {
|
|
896 |
this.children.get(i).setDirty(dirty);
|
|
897 |
}
|
873 |
898 |
}
|
874 |
899 |
}
|
875 |
|
|
876 |
900 |
|
|
901 |
|
877 |
902 |
/**
|
878 |
903 |
* Gets the value of the specified key in parameters, local result node or
|
879 |
904 |
* default preferences nodes.
|
... | ... | |
939 |
964 |
public String getStringParameterValue(String key) {
|
940 |
965 |
return TXMPreferences.getString(key, this, this.commandPreferencesNodePath);
|
941 |
966 |
}
|
942 |
|
|
|
967 |
|
943 |
968 |
/**
|
944 |
969 |
* Gets the value of the specified key in parameters, local result node or
|
945 |
970 |
* default preferences nodes.
|
... | ... | |
950 |
975 |
public Date getDateParameterValue(String key) {
|
951 |
976 |
return TXMPreferences.getDate(key, this, this.commandPreferencesNodePath);
|
952 |
977 |
}
|
|
978 |
|
|
979 |
/**
|
|
980 |
* Gets the value of the specified key in parameters, local result node or
|
|
981 |
* default preferences nodes.
|
|
982 |
*
|
|
983 |
* @param key
|
|
984 |
* @return
|
|
985 |
*/
|
|
986 |
public File getFileParameterValue(String key) {
|
|
987 |
String v = TXMPreferences.getString(key, this, this.commandPreferencesNodePath);
|
|
988 |
if (v != null && v.length() > 0) {
|
|
989 |
return new File(v);
|
|
990 |
} else {
|
|
991 |
return null;
|
|
992 |
}
|
|
993 |
}
|
953 |
994 |
|
954 |
995 |
|
955 |
996 |
/**
|
... | ... | |
972 |
1013 |
return TXMPreferences.isEmpty(this.commandPreferencesNodePath, key);
|
973 |
1014 |
}
|
974 |
1015 |
|
975 |
|
|
976 |
|
|
977 |
1016 |
/**
|
978 |
1017 |
* Stores the specified parameters pairs of key/value in a local node dedicated to the specified result. The node qualifier is generated by the <code>TXMResult.getUUID</code> method.
|
979 |
1018 |
*
|
... | ... | |
1013 |
1052 |
this.saveParameter("class", this.getClass().getName()); //$NON-NLS-1$
|
1014 |
1053 |
|
1015 |
1054 |
this.saveParameter(TXMPreferences.RESULT_PARAMETERS_NODE_PATH, this.parametersNodePath);
|
1016 |
|
|
|
1055 |
|
1017 |
1056 |
// FIXME: old version that not work well if a bundle has no preference initializer
|
1018 |
1057 |
//this.saveParameter(TXMPreferences.BUNDLE_ID, this.commandPreferencesNodePath);
|
1019 |
1058 |
// FIXME: new version
|
1020 |
1059 |
this.saveParameter(TXMPreferences.BUNDLE_ID, FrameworkUtil.getBundle(getClass()).getSymbolicName());
|
1021 |
|
|
1022 |
|
|
1023 |
|
|
|
1060 |
|
|
1061 |
|
|
1062 |
|
1024 |
1063 |
if (this.parent != null) {
|
1025 |
1064 |
this.saveParameter(TXMPreferences.PARENT_PARAMETERS_NODE_PATH, this.parent.getParametersNodePath());
|
1026 |
1065 |
}
|
... | ... | |
1045 |
1084 |
f.getType().isAssignableFrom(double.class) || f.getType().isAssignableFrom(Double.class) ||
|
1046 |
1085 |
f.getType().isAssignableFrom(float.class) || f.getType().isAssignableFrom(Float.class) ||
|
1047 |
1086 |
f.getType().isAssignableFrom(boolean.class) || f.getType().isAssignableFrom(Boolean.class) ||
|
1048 |
|
f.getType().isAssignableFrom(String.class)
|
|
1087 |
f.getType().isAssignableFrom(String.class) || f.getType().isAssignableFrom(File.class)
|
1049 |
1088 |
|
1050 |
1089 |
// FIXME: do not pass a Serializable for now
|
1051 |
1090 |
//|| !f.getType().isAssignableFrom(Serializable.class)
|
... | ... | |
1147 |
1186 |
if (parameter == null || parameter.type() != parameterType) {
|
1148 |
1187 |
continue;
|
1149 |
1188 |
}
|
1150 |
|
|
|
1189 |
|
1151 |
1190 |
String key = parameter.key();
|
1152 |
1191 |
|
1153 |
1192 |
if (key.isEmpty()) {
|
... | ... | |
1177 |
1216 |
else if (f.getType().isAssignableFrom(Date.class)) {
|
1178 |
1217 |
value = this.getDateParameterValue(key);
|
1179 |
1218 |
}
|
|
1219 |
else if (f.getType().isAssignableFrom(File.class)) {
|
|
1220 |
value = this.getFileParameterValue(key);
|
|
1221 |
}
|
1180 |
1222 |
// FIXME: test to automate other type creation as Property => problem here is that org.txm.core doesn't know the plug-in org.txm.searchengine.cqp.core
|
1181 |
1223 |
// could be done using reflection. Get the field runtime class, then get and call the constructor
|
1182 |
1224 |
// else if (f.getType().isAssignableFrom(Property.class)) {
|
... | ... | |
1265 |
1307 |
if (targetField != null) {
|
1266 |
1308 |
targetField.setAccessible(true);
|
1267 |
1309 |
targetField.set(this, value);
|
1268 |
|
|
|
1310 |
|
1269 |
1311 |
// Log
|
1270 |
1312 |
String message = "TXMResult.setParameter(): " + this.getClass().getSimpleName() + ": setting parameter " + key + " = " + value; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
1271 |
1313 |
Log.finest(message);
|
1272 |
|
|
|
1314 |
|
1273 |
1315 |
}
|
1274 |
1316 |
else if (this.parent != null && propagateToParent) {
|
1275 |
1317 |
this.parent.setParameter(key, value, propagateToParent);
|
... | ... | |
1309 |
1351 |
this.clean();
|
1310 |
1352 |
|
1311 |
1353 |
if (this.parent != null) {
|
1312 |
|
|
1313 |
|
TXMResult parent = this.parent;
|
1314 |
|
|
|
1354 |
|
1315 |
1355 |
this.parent.removeChild(this);
|
1316 |
|
|
|
1356 |
|
1317 |
1357 |
}
|
1318 |
1358 |
this.parent = null;
|
1319 |
1359 |
return true;
|
... | ... | |
1327 |
1367 |
/**
|
1328 |
1368 |
* Deletes all non persistent results and saves the results to persist.
|
1329 |
1369 |
*/
|
1330 |
|
public static void deleteAllNonPersistentResults() {
|
1331 |
|
List<TXMResult> todo = Toolbox.workspace.getChildren();
|
|
1370 |
public static void deleteAllNonPersistentResults(TXMResult root) {
|
|
1371 |
List<TXMResult> todo = root.getChildren();
|
1332 |
1372 |
while (todo.size() > 0) {
|
1333 |
1373 |
TXMResult r = null;
|
1334 |
|
r = todo.remove(0);
|
1335 |
|
todo.addAll(0, r.getChildren());
|
1336 |
|
if (r.mustBePersisted()) {
|
1337 |
|
TXMPreferences.flush(r);
|
1338 |
|
}
|
1339 |
|
else {
|
1340 |
|
Log.finest("TXMResult.deleteAllNonPersistentResults(): Deleting result " + r.getSimpleName() + " of type " + r.getClass().getSimpleName() + ".");
|
1341 |
|
TXMPreferences.delete(r);
|
1342 |
|
}
|
|
1374 |
r = todo.remove(0);
|
|
1375 |
todo.addAll(0, r.getChildren());
|
|
1376 |
if (r.mustBePersisted()) {
|
|
1377 |
TXMPreferences.flush(r);
|
|
1378 |
}
|
|
1379 |
else {
|
|
1380 |
Log.finest("TXMResult.deleteAllNonPersistentResults(): Deleting result " + r.getSimpleName() + " of type " + r.getClass().getSimpleName() + ".");
|
|
1381 |
TXMPreferences.delete(r);
|
|
1382 |
}
|
1343 |
1383 |
}
|
1344 |
1384 |
}
|
1345 |
1385 |
|
... | ... | |
1444 |
1484 |
return false;
|
1445 |
1485 |
}
|
1446 |
1486 |
|
1447 |
|
|
|
1487 |
|
1448 |
1488 |
/**
|
1449 |
1489 |
* Checks if the result has at least one child visible.
|
1450 |
1490 |
* @return true if the result has at least one child visible
|
... | ... | |
1452 |
1492 |
public boolean hasVisibleChild() {
|
1453 |
1493 |
return !this.getChildren(true).isEmpty();
|
1454 |
1494 |
}
|
1455 |
|
|
1456 |
|
|
|
1495 |
|
|
1496 |
|
1457 |
1497 |
/**
|
1458 |
1498 |
* Gets all the children results (not a clone).
|
1459 |
1499 |
*
|
... | ... | |
1514 |
1554 |
public void deleteChildren() {
|
1515 |
1555 |
deleteChildren(null);
|
1516 |
1556 |
}
|
1517 |
|
|
|
1557 |
|
1518 |
1558 |
/**
|
1519 |
1559 |
* Deletes the children of the specified class.
|
1520 |
1560 |
* @param type
|
... | ... | |
1566 |
1606 |
public List<TXMResult> getDeepChildren(Class<? extends TXMResult> clazz) {
|
1567 |
1607 |
return TXMResult.getDeepChildren(this, clazz);
|
1568 |
1608 |
}
|
1569 |
|
|
|
1609 |
|
1570 |
1610 |
/**
|
1571 |
1611 |
* Gets the children of all the branch in a flat list.
|
1572 |
1612 |
*
|
... | ... | |
1575 |
1615 |
public static List<TXMResult> getDeepChildren(TXMResult r) {
|
1576 |
1616 |
return TXMResult.getDeepChildren(r, null);
|
1577 |
1617 |
}
|
1578 |
|
|
|
1618 |
|
1579 |
1619 |
/**
|
1580 |
1620 |
* Gets the children of all the branch in a flat list.
|
1581 |
1621 |
*
|
... | ... | |
1603 |
1643 |
return results.get(i); // a direct children is the node we are looking for
|
1604 |
1644 |
}
|
1605 |
1645 |
}
|
1606 |
|
|
|
1646 |
|
1607 |
1647 |
for (int i = 0; i < results.size(); i++) {
|
1608 |
1648 |
TXMResult r = getResult(results.get(i), nodePath);
|
1609 |
1649 |
if (r != null) {
|
... | ... | |
1705 |
1745 |
public boolean isChild(TXMResult child) {
|
1706 |
1746 |
return this.getDeepChildren().contains(child);
|
1707 |
1747 |
}
|
1708 |
|
|
|
1748 |
|
1709 |
1749 |
/**
|
1710 |
1750 |
* Gets the sibling nodes of this node result.
|
1711 |
1751 |
*/
|
... | ... | |
1738 |
1778 |
public boolean isVisible() {
|
1739 |
1779 |
return this.visible;
|
1740 |
1780 |
}
|
1741 |
|
|
|
1781 |
|
1742 |
1782 |
public boolean isParentVisible() {
|
1743 |
1783 |
return parent != null && (parent.isVisible() || parent.isInternalPersistable());
|
1744 |
1784 |
}
|
... | ... | |
1795 |
1835 |
*/
|
1796 |
1836 |
public abstract String getDetails();
|
1797 |
1837 |
|
1798 |
|
|
|
1838 |
|
1799 |
1839 |
/**
|
1800 |
1840 |
* Gets a message indicating the start of computing.
|
1801 |
1841 |
* Dedicated to indicate the start of computing and, for example, the parameters used for the computing.
|
... | ... | |
1806 |
1846 |
public String getComputingStartMessage() {
|
1807 |
1847 |
return "Computing "+this.getClass().getSimpleName()+"...";
|
1808 |
1848 |
}
|
1809 |
|
// public abstract String getComputingStartMessage();
|
|
1849 |
// public abstract String getComputingStartMessage();
|
1810 |
1850 |
|
1811 |
|
|
|
1851 |
|
1812 |
1852 |
/**
|
1813 |
1853 |
* Gets a message indicating the computing is done.
|
1814 |
1854 |
* Dedicated to indicate the end of computing and, for example, some informations about the result (eg. : 12 matches found, No matches found, etc.).
|
... | ... | |
1819 |
1859 |
public String getComputingDoneMessage() {
|
1820 |
1860 |
return "";
|
1821 |
1861 |
}
|
1822 |
|
// public abstract String getComputingDoneMessage();
|
|
1862 |
// public abstract String getComputingDoneMessage();
|
1823 |
1863 |
|
1824 |
|
|
1825 |
|
|
1826 |
|
|
1827 |
|
|
1828 |
1864 |
|
1829 |
|
|
|
1865 |
|
|
1866 |
|
|
1867 |
|
|
1868 |
|
|
1869 |
|
1830 |
1870 |
/**
|
1831 |
1871 |
* Gets the user name if exists otherwise, the lazy name if exists, otherwise the simple name.
|
1832 |
1872 |
*
|
... | ... | |
1853 |
1893 |
return "..."; //$NON-NLS-1$
|
1854 |
1894 |
}
|
1855 |
1895 |
|
1856 |
|
// /**
|
1857 |
|
// * Returns a string representation of an unique ID for the result.
|
1858 |
|
// *
|
1859 |
|
// * @return
|
1860 |
|
// */
|
1861 |
|
// public String getUUID() {
|
1862 |
|
// return this.uniqueID;
|
1863 |
|
// }
|
|
1896 |
// /**
|
|
1897 |
// * Returns a string representation of an unique ID for the result.
|
|
1898 |
// *
|
|
1899 |
// * @return
|
|
1900 |
// */
|
|
1901 |
// public String getUUID() {
|
|
1902 |
// return this.uniqueID;
|
|
1903 |
// }
|
1864 |
1904 |
|
1865 |
1905 |
/**
|
1866 |
1906 |
* Gets a string representing the result that can be used as a file name (eg. for exporting in file).
|
... | ... | |
1924 |
1964 |
public TXMResult clone() {
|
1925 |
1965 |
return clone(null, true);
|
1926 |
1966 |
}
|
1927 |
|
|
|
1967 |
|
1928 |
1968 |
public TXMResult clone(boolean all) {
|
1929 |
1969 |
return clone(null, all);
|
1930 |
1970 |
}
|
... | ... | |
1939 |
1979 |
try {
|
1940 |
1980 |
String newNodePath = this.getProject().getParametersNodeRootPath()+ createUUID() + "_" + this.getClass().getSimpleName();
|
1941 |
1981 |
TXMPreferences.cloneNode(this.getParametersNodePath(), newNodePath);
|
1942 |
|
|
|
1982 |
|
1943 |
1983 |
if (newParent != null) { // change the cloned node parent preference
|
1944 |
1984 |
TXMPreferences.put(newNodePath, TXMPreferences.PARENT_PARAMETERS_NODE_PATH, newParent.getParametersNodePath());
|
1945 |
1985 |
}
|
1946 |
1986 |
clone = this.getClass().getDeclaredConstructor(String.class).newInstance(newNodePath);
|
1947 |
|
|
|
1987 |
|
1948 |
1988 |
if (all) {
|
1949 |
1989 |
for (TXMResult child : this.children) {
|
1950 |
1990 |
child.clone(clone, all);
|
... | ... | |
1961 |
2001 |
try {
|
1962 |
2002 |
Properties props = new Properties();
|
1963 |
2003 |
props.load(IOUtils.getReader(parameters));
|
1964 |
|
|
|
2004 |
|
1965 |
2005 |
// some tests before...
|
1966 |
2006 |
String className = props.getProperty("class");
|
1967 |
2007 |
if (className == null || className.length() == 0) {
|
1968 |
2008 |
System.out.println("** Error: No class internal parameter set.");
|
1969 |
2009 |
return false;
|
1970 |
2010 |
}
|
1971 |
|
|
|
2011 |
|
1972 |
2012 |
if (this.getClass().getName().equals(className)) {
|
1973 |
2013 |
for (Object p : props.keySet()) {
|
1974 |
2014 |
String ps = p.toString();
|
... | ... | |
1987 |
2027 |
}
|
1988 |
2028 |
return true;
|
1989 |
2029 |
}
|
1990 |
|
|
|
2030 |
|
1991 |
2031 |
/**
|
1992 |
2032 |
* import a result from a parameter file
|
1993 |
2033 |
* @param allparameters the parameters file
|
... | ... | |
1997 |
2037 |
try {
|
1998 |
2038 |
Properties props = new Properties();
|
1999 |
2039 |
props.load(IOUtils.getReader(parameters));
|
2000 |
|
|
|
2040 |
|
2001 |
2041 |
// some tests before...
|
2002 |
2042 |
String className = props.getProperty("class");
|
2003 |
2043 |
if (className == null || className.length() == 0) {
|
2004 |
2044 |
System.out.println("** Error: No class internal parameter set.");
|
2005 |
2045 |
return null;
|
2006 |
2046 |
}
|
2007 |
|
|
|
2047 |
|
2008 |
2048 |
String bundleId = props.getProperty("bundle_id");
|
2009 |
2049 |
if (bundleId == null || bundleId.length() == 0) {
|
2010 |
2050 |
System.out.println("** Error: No bundle_id internal parameter set.");
|
2011 |
2051 |
return null;
|
2012 |
2052 |
}
|
2013 |
|
|
|
2053 |
|
2014 |
2054 |
Bundle bundle = Platform.getBundle(bundleId);
|
2015 |
2055 |
if (bundle == null) {
|
2016 |
2056 |
Log.finest("** Error: can not restore object with bundle name " + bundleId); //$NON-NLS-1$
|
2017 |
2057 |
return null;
|
2018 |
2058 |
}
|
2019 |
|
|
|
2059 |
|
2020 |
2060 |
// copy parameters
|
2021 |
2061 |
String newNodePath = this.getProject().getParametersNodeRootPath()+ createUUID() + "_" + className;
|
2022 |
2062 |
TXMPreferences.put(newNodePath, TXMPreferences.PARENT_PARAMETERS_NODE_PATH, this.getParametersNodePath());
|
... | ... | |
2026 |
2066 |
if (TXMPreferences.RESULT_PARAMETERS_NODE_PATH.equals(ps)) continue;
|
2027 |
2067 |
TXMPreferences.put(newNodePath, ps, props.getProperty(ps, ""));
|
2028 |
2068 |
}
|
2029 |
|
|
|
2069 |
|
2030 |
2070 |
// create instance
|
2031 |
2071 |
Class<?> cl = bundle.loadClass(className);
|
2032 |
2072 |
Constructor<?> cons = null;
|
... | ... | |
2041 |
2081 |
clazz = clazz.getSuperclass();
|
2042 |
2082 |
}
|
2043 |
2083 |
}
|
2044 |
|
|
|
2084 |
|
2045 |
2085 |
if (cons == null) {
|
2046 |
2086 |
System.out.println(NLS.bind("Cannot import {0} in {1}", parameters, this));
|
2047 |
2087 |
} else {
|
... | ... | |
2050 |
2090 |
System.out.println(NLS.bind("{0} imported", result));
|
2051 |
2091 |
return result;
|
2052 |
2092 |
}
|
2053 |
|
|
|
2093 |
|
2054 |
2094 |
} catch (Exception e) {
|
2055 |
2095 |
System.out.println(NLS.bind("Fail to import result from {0}: {1}", parameters, e));
|
2056 |
2096 |
Log.printStackTrace(e);
|
2057 |
2097 |
}
|
2058 |
2098 |
return null;
|
2059 |
2099 |
}
|
2060 |
|
|
|
2100 |
|
2061 |
2101 |
/**
|
2062 |
2102 |
* Set the TXMResult parameters
|
2063 |
2103 |
*
|
... | ... | |
2143 |
2183 |
return this.compute(monitor, true);
|
2144 |
2184 |
}
|
2145 |
2185 |
|
2146 |
|
|
|
2186 |
|
2147 |
2187 |
/**
|
2148 |
2188 |
* Computes the result if:
|
2149 |
2189 |
* - it can be computed (checking if all mandatory parameters are set)
|
... | ... | |
2154 |
2194 |
* @return
|
2155 |
2195 |
*/
|
2156 |
2196 |
protected boolean compute(IProgressMonitor monitor, boolean deepComputing) {
|
2157 |
|
|
|
2197 |
|
2158 |
2198 |
if (this.computing) {
|
2159 |
2199 |
return true;
|
2160 |
2200 |
}
|
2161 |
|
|
|
2201 |
|
2162 |
2202 |
this.computing = true;
|
2163 |
|
|
2164 |
|
|
|
2203 |
|
|
2204 |
|
2165 |
2205 |
// no changes to do
|
2166 |
2206 |
// FIXME: SJ: we need to do do some actions even if the object is locked, eg. updating parameters, saving parameters, etc.
|
2167 |
2207 |
// FIXME MD: nope the parameters must not move and will be saved in the current state
|
... | ... | |
2169 |
2209 |
this.computing = false;
|
2170 |
2210 |
return true;
|
2171 |
2211 |
}
|
2172 |
|
|
2173 |
|
|
|
2212 |
|
|
2213 |
|
2174 |
2214 |
try {
|
2175 |
2215 |
|
2176 |
2216 |
Log.finest("*** TXMResult.compute(): " + this.getClass().getSimpleName() + ": starting computing process...");
|
2177 |
2217 |
|
2178 |
|
|
|
2218 |
|
2179 |
2219 |
// FIXME: SJ: see if this skipComputing tests is still useful? is it possible to directly return instead?
|
2180 |
2220 |
// en fait voir ChartResult.compute() if(super.compute(monitor, true, false)), je pense que le prob vient du fait que si on retourne false dans TXMResult.compute() alors renderChart() ne sera pas appelé
|
2181 |
2221 |
// il faudrait retourner un état: skipped, computed, error, etc.
|
... | ... | |
2197 |
2237 |
|
2198 |
2238 |
// update the dirty state from history if a parameter has changed since last computing
|
2199 |
2239 |
this.updateDirtyFromHistory();
|
2200 |
|
|
|
2240 |
|
2201 |
2241 |
// check if the result is dirty
|
2202 |
2242 |
if (!this.isDirty()) {
|
2203 |
2243 |
Log.finest("--- TXMResult.compute(): " + this.getClass().getSimpleName() + ": result parameters have not changed since last computing, computing skipped.");
|
... | ... | |
2206 |
2246 |
|
2207 |
2247 |
if(!skipComputing) {
|
2208 |
2248 |
|
2209 |
|
|
|
2249 |
|
2210 |
2250 |
// Debug
|
2211 |
2251 |
Log.finest("+++ TXMResult.compute(): " + this.getClass().getSimpleName() + ": computing result of type " + this.getClass() + "...");
|
2212 |
2252 |
|
... | ... | |
2219 |
2259 |
|
2220 |
2260 |
//Log.info(this.getComputingStartMessage());
|
2221 |
2261 |
|
2222 |
|
|
|
2262 |
|
|
2263 |
if (monitor != null) monitor.subTask(this.getSimpleName()+"...");
|
2223 |
2264 |
// Computing
|
2224 |
2265 |
if (!this._compute()) {
|
2225 |
2266 |
Log.finest("TXMResult.compute(): " + this.getClass().getSimpleName() + ": computing failed.");
|
2226 |
2267 |
this.computing = false;
|
2227 |
2268 |
return false;
|
2228 |
2269 |
}
|
2229 |
|
|
|
2270 |
|
2230 |
2271 |
}
|
2231 |
2272 |
|
2232 |
2273 |
// clear the lazy name, no more needed since the object has been computed and getSimpleName() can now work
|
... | ... | |
2239 |
2280 |
if(!skipComputing) {
|
2240 |
2281 |
|
2241 |
2282 |
// store last used parameters
|
2242 |
|
// this.updateLastParameters();
|
|
2283 |
// this.updateLastParameters();
|
2243 |
2284 |
if (this.hasBeenComputedOnce// don't update the computing date if the object has been lazy loaded
|
2244 |
2285 |
|| this.lastComputingDate == null) { // set the update date if never computed once
|
2245 |
2286 |
this.lastComputingDate = Calendar.getInstance().getTime(); // update this internal parameter before saving parameters
|
2246 |
2287 |
}
|
2247 |
|
|
|
2288 |
|
2248 |
2289 |
if (!this.autoSaveParametersFromAnnotations()) {
|
2249 |
2290 |
Log.severe("TXMResult.compute(): " + this.getClass().getSimpleName() + ": failed to save parameters from annotations for " + this.getName() + ".");
|
2250 |
2291 |
}
|
... | ... | |
2260 |
2301 |
|
2261 |
2302 |
this.dirty = false; // the computing was successful, the result is no more dirty
|
2262 |
2303 |
this.hasBeenComputedOnce = true;
|
2263 |
|
|
|
2304 |
|
2264 |
2305 |
if (this.altered) {
|
2265 |
2306 |
Log.finest(NLS.bind("TXMResult.compute(): Warning {0} modifications have been lost.", this.getSimpleName()));
|
2266 |
2307 |
}
|
2267 |
2308 |
this.altered = false;
|
2268 |
2309 |
Log.finest("TXMResult.compute(): " + this.getClass().getSimpleName() + ": computing of result type " + this.getClass() + " done.");
|
2269 |
|
|
|
2310 |
|
2270 |
2311 |
//Log.info(this.getComputingDoneMessage());
|
2271 |
2312 |
|
2272 |
|
|
|
2313 |
|
2273 |
2314 |
}
|
2274 |
|
|
2275 |
|
|
|
2315 |
|
|
2316 |
|
2276 |
2317 |
// Children computing
|
2277 |
2318 |
if(!skipComputing
|
2278 |
2319 |
|| this.altered // FIXME: SJ: fix for computing LexicalTable children even if the LT is not dirty but only altered, need to define if it's a temporary fix or not
|
2279 |
2320 |
) {
|
2280 |
|
|
|
2321 |
|
|
2322 |
if (monitor != null && children.size() > 1) monitor.beginTask("Computing children of "+this, children.size());
|
2281 |
2323 |
// set the children as dirty since the result has changed
|
2282 |
2324 |
for (int i = 0; i < this.children.size(); i++) {
|
2283 |
2325 |
this.children.get(i).setDirty();
|
2284 |
2326 |
}
|
2285 |
|
|
|
2327 |
|
2286 |
2328 |
// Children cascade computing (if parent == null then it is the Workspace (Tree root))
|
2287 |
2329 |
if (deepComputing && this.parent != null) {
|
2288 |
|
|
|
2330 |
|
2289 |
2331 |
Log.finest("TXMResult.compute(): " + this.getClass().getSimpleName() + ": cascade computing of " + this.children.size() + " child(ren).");
|
2290 |
|
|
|
2332 |
|
2291 |
2333 |
for (int i = 0; i < this.children.size(); i++) {
|
2292 |
2334 |
this.children.get(i).compute(monitor, deepComputing);
|
|
2335 |
|
|
2336 |
if (monitor != null && children.size() > 1) monitor.worked(1);
|
2293 |
2337 |
}
|
2294 |
2338 |
}
|
2295 |
2339 |
}
|
2296 |
|
|
|
2340 |
|
2297 |
2341 |
}
|
2298 |
2342 |
catch (Exception e) {
|
2299 |
2343 |
e.printStackTrace();
|
... | ... | |
2558 |
2602 |
child.setUserPersistable(userPersistable);
|
2559 |
2603 |
}
|
2560 |
2604 |
}
|
2561 |
|
|
|
2605 |
|
2562 |
2606 |
// directly save and flush the preference
|
2563 |
2607 |
try {
|
2564 |
2608 |
if (this.isUserPersistable()) {
|
... | ... | |
2606 |
2650 |
public ArrayList<HashMap<String, Object>> getParametersHistory() {
|
2607 |
2651 |
return parametersHistory;
|
2608 |
2652 |
}
|
2609 |
|
|
|
2653 |
|
2610 |
2654 |
/**
|
2611 |
2655 |
* Gets the last computing date.
|
2612 |
2656 |
* @return the last computing date
|
... | ... | |
2622 |
2666 |
public Date getCreationDate() {
|
2623 |
2667 |
return this.creationDate;
|
2624 |
2668 |
}
|
2625 |
|
|
2626 |
2669 |
|
|
2670 |
|
2627 |
2671 |
public boolean toParametersFile(File outfile) throws IOException {
|
2628 |
2672 |
return TXMPreferences.flush(this, outfile);
|
2629 |
2673 |
}
|