I apologize for a lengthy question, but I really need your help. As a part of our project, I'm currently working on a search engine, that updates results list on the fly: the user types in the first 4 characters and up, and as he types, the results list changes. The search value is typed in a text box, while the results are displayed in a Richfaces component rich:extendedDataTable below. If the search value is removed, the result list is empty. I was able to get that working, however, after a few tries I get ConcurrentModificationException, thrown by the component itself. The initial list I am searching comes from the properties file (because I don't want the search to hit database every time the user types something). I've been banging my head over it for months. What am I missing? Let me show you what I've done:
This is the input text that should trigger the search logic (I make sure that the table does not get updated when the value is less than 4 characters or if the user presses keys, like arrows, shift, and ctrl - this function is "returnunicode(event)"):
<h:inputText id="firmname" value="#{ExtendedTableBean.searchValue}">
<a4j:support reRender="resultsTable" onsubmit="
if ((this.value.length<4 && this.value.length>0) || !returnunicode(event)) {
return false;
}" actionListener="#{ExtendedTableBean.searchForResults}" event="onkeyup" />
</h:inputText>
Action listener is what should update the list. Here is the extendedDataTable, right below the inputText:
<rich:extendedDataTable tableState="#{ExtendedTableBean.tableState}" var="item"
id="resultsTable" value="#{ExtendedTableBean.dataModel}">
... <%-- I'm listing columns here --%>
</rich:extendedDataTable>
Now, if it's ok, I would like to show you the back-end code. I only left the logic that's important to my issue.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.beans;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.richfaces.model.DataProvider;
import org.richfaces.model.ExtendedTableDataModel;
public class ExtendedTableBean {
private String sortMode="single";
private ExtendedTableDataModel<ResultObject> dataModel;
//ResultObject is a simple pojo and getResultsPerValue is a method that
//read the data from the properties file, assigns it to this pojo, and
//adds a pojo to the list
private Object tableState;
private List<ResultObject> results = new CopyOnWriteArrayList<ResultObject>();
private List<ResultObject> selectedResults =
new CopyOnWriteArrayList<ResultObject>();
private String searchValue;
/**
* This is the action listener that the user triggers, by typing the search value
*/
public void searchForResults(ActionEvent e) {
synchronized(results) {
results.clear();
}
//I don't think it's necessary to clear results list all the time, but here
//I also make sure that we start searching if the value is at least 4
//characters long
if (this.searchValue.length() > 3) {
results.clear();
updateTableList();
} else {
results.clear();
}
dataModel = null; // to force the dataModel to be updated.
}
public List<ResultObject> getResultsPerValue(String searchValue) {
List<ResultObject> resultsList = new CopyOnWriteArrayList<ResultObject>();
//Logic for reading data from the properties file, populating ResultObject
//and adding it to the list
return resultsList;
}
/**
* This method updates a firm list, based on a search value
*/
public void updateTableList() {
try {
List<ResultObject> searchedResults = getResultsPerValue(searchValue);
//Once the results have been retrieved from the properties, empty
//current firm list and replace it with what was found.
synchronized(firms) {
firms.clear();
firms.addAll(searchedFirms);
}
} catch(Throwable xcpt) {
//Exception handling
}
}
/**
* This is a recursive method, that's used to constantly keep updating the
* table list.
*/
public synchronized ExtendedTableDataModel<ResultObject> getDataModel() {
try {
if (dataModel == null) {
dataModel = new ExtendedTableDataModel<ResultObject>(
new DataProvider<ResultObject>() {
public ResultObject getItemByKey(Object key) {
try {
for(ResultObject c : results) {
if (key.equals(getKey(c))){
return c;
}
}
} catch (Exception ex) {
//Exception handling
}
return null;
}
public List<ResultObject> getItemsByRange(
int firstRow, int endRow) {
return Collections.unmodifiableList(results.subList(firstRow, endRow));
}
public Object getKey(ResultObject item) {
return item.getResultName();
}
public int getRowCount() {
return results.size();
}
});
}
} catch (Exception ex) {
//Exception handling
}
return dataModel;
}
//Getters and setters
}
And like I said, it works fine, but when the user types fast or deletes fast (it's hard to catch exactly when it happens), ConcurrentModificationException is thrown. Here's what it looks like exactly:
WARNING: executePhase(RENDER_RESPONSE 6,com.sun.faces.context.FacesContextImpl#4406b8) threw exception
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at org.richfaces.model.ExtendedTableDataModel.walk(ExtendedTableDataModel.java:108)
at org.ajax4jsf.component.UIDataAdaptorBase.walk(UIDataAdaptorBase.java:1156)
at org.richfaces.renderkit.AbstractExtendedRowsRenderer.encodeRows(AbstractExtendedRowsRenderer.java:159)
at org.richfaces.renderkit.AbstractExtendedRowsRenderer.encodeRows(AbstractExtendedRowsRenderer.java:142)
at org.richfaces.renderkit.AbstractExtendedRowsRenderer.encodeChildren(AbstractExtendedRowsRenderer.java:191)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:812)
at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:277)
at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:166)
at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:83)
at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:157)
...
Synchronization of the Java code has never been my strongest side, I don't know what would be causing the error and, most importantly, how can I get rid of it. I'm aware, that Richfaces 4.0 has made a lot of changes to rich:extendedDataTable component, I've heard that this was an issue before and now it's resolved. However, I don't have time to upgrade the whole application to Richfaces 4.0 (it's going to be done in phase 2), this is just the small part of the whole project. If there is no way to resolve the issue, described above, then maybe there's a workaround? Or, perhaps, there are other ways to implement similar kind of search, using plain JSF (provided that it's are quick enough to implement). I will appreciate any kind of help or advice on that matter. I hope the code is understandable enough, but if not, let me know, I'll explain further. Thank you in advance, I really appreciate your help.
The problem is concurrent ajax calls to the server. Use the attribute "eventsQueue" in a4j:support. Usually, you should always use "eventsQueue" in any ajax component, with all "eventsQueue" in the same page referencing the same queue, unless you have a very good reason to not doing it.
Also, you'll probably want to look into another ajax attribute: "ajaxSingle".
Related
I am developing a plugin for intellij and I want to add custom suggestions to xml editor based on a xsd. Up to now I can get required suggestions from xsd file.
I have implemented a completion contributor for xml as follows
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.xml.XmlElementType;
import com.intellij.util.ProcessingContext;
import com.intellij.lang.xml.*;
import org.jetbrains.annotations.NotNull;
public class SimpleCompletionContributor extends CompletionContributor {
public SimpleCompletionContributor() {
extend(CompletionType.BASIC,PlatformPatterns.psiElement(XmlElementType.XML_ATTRIBUTE_VALUE).withLanguage(XMLLanguage.INSTANCE),
new CompletionProvider<CompletionParameters>() {
public void addCompletions(#NotNull CompletionParameters parameters,
ProcessingContext context,
#NotNull CompletionResultSet resultSet) {
resultSet.addElement(LookupElementBuilder.create("Hello"));
}
}
);
}
}
but this did not provide any suggestion. but when I implement custom language it works. My objective is to view the context of the cursor position and provide suggestion based on it. as an example when user starts a tag on xml file plugin should provide attributes as code completion. I'm new to this Custom language.
So can anyone help me with this completion contributor?
finally i found a way to solve this problem
here is my code
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
public class ScalaXMLCompletionContributor extends CompletionContributor {
public ScalaXMLCompletionContributor() {
final RelativeNodes rlt = new RelativeNodes();//this is a class to get siblings and children from a sample xml file generated by a given xsd
/*if the parameter position is an xml attribute provide attributes using given xsd*/
extend(CompletionType.BASIC,
PlatformPatterns.psiElement(), new CompletionProvider<CompletionParameters>() {
public void addCompletions(#NotNull CompletionParameters parameters,//completion parameters contain details of the curser position
ProcessingContext context,
#NotNull CompletionResultSet resultSet) {//result set contains completion details to suggest
if (parameters.getPosition().getContext().toString() == "XmlAttribute") {//check whether scala text editors position is an xml attribute position eg: <name |
try {
String[] suggestions = rlt.getAttribute(parameters.getPosition().getParent().getParent().getFirstChild().getNextSibling().getText().replaceFirst("IntellijIdeaRulezzz", ""));//extract text from completion parameter and get required suggestions from RelativeNodes
int i = 0;
do {
resultSet.addElement(LookupElementBuilder.create(suggestions[i]));//add suggestions to resultset to suggest in editor
i++;
} while (suggestions[i] != null);
} catch (NullPointerException e) {
}
}
}
}
);
}
}
in this case we can obtain cursor position and tokens related to curser position by completion parameters and we can inject suggestions using cpmpletion resultset. this can be implemented in scala language too.
to register completion contributor in plugin xml
<extensions defaultExtensionNs="com.intellij">
<completion.contributor language="Scala" implementationClass="com.hsr.ScalaXMLCompletionContributor"/>
</extensions>
JavaDoc for com.intellij.codeInsight.completion.CompletionContributor contains FAQ.
The last question addresses debugging not working completion.
In my case issue was language="Java", whereas all caps expected.
I'm trying to analyse some bits of Java-code, looking if the code is written too complexly. I start with a String containing the contents of a Java-class.
From there I want to retrieve, given a function-name, the "inner code" by that function. In this example:
public class testClass{
public int testFunction(char x) throws Exception{
if(x=='a'){
return 1;
}else if(x=='{'){
return 2;
}else{
return 3;
}
}
public int testFunctionTwo(int y){
return y;
}
}
I want to get, when I call String code = getcode("testFunction");, that code contains if(x=='a'){ ... return 3; }. I've made the input code extra ugly, to demonstrate some of the problems one might encounter when doing character-by-character-analysis (because of the else if, the curly brackets will no longer match, because of the Exception thrown, the function declaration is not of the form functionName{ //contents }, etc.)
Is there a solid way to get the contents of testFunction, or should I implement all problems described manually?
You need to a java parser. I worked too with QDox. it is easy to use. example here:
import com.thoughtworks.qdox.JavaProjectBuilder;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaMethod;
import java.io.File;
import java.io.IOException;
public class Parser {
public void parseFile() throws IOException {
File file = new File("/path/to/testClass.java");
JavaProjectBuilder builder = new JavaProjectBuilder();
builder.addSource(file);
for (JavaClass javaClass : builder.getClasses()) {
if (javaClass.getName().equals("testClass")) {
for (JavaMethod javaMethod : javaClass.getMethods()) {
if (javaMethod.getName().equals("testMethod")) {
System.out.println(javaMethod.getSourceCode());
}
}
}
}
}
}
Have you considered using a parser to read your code? There are a lot of parsers out there, the last time I worked on a problem like this http://qdox.codehaus.org made short work of these kinds of problems.
In a javafx2 application, a ComboBox should present a list of items, in the example they are String s for simplicity.
This list contains a null item, since i want the user to be allowed to make no choice.
Since I was playing with the converter property of the ComboBox, I wondered if I could use it to provide a nice representation for the no-choice case, for example "[none]" instead of an empty line.
But i've discovered that the toString(Object object) is never called for the null item.
Here follows the shortest code that reproduces the case. Version information included.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class T05 extends Application {
#Override public void start(Stage primaryStage) throws Exception {
System.out.println(System.getProperty("java.runtime.version"));
System.out.println(System.getProperty("javafx.runtime.version"));
System.out.println(System.getProperty("os.version"));
System.out.println(System.getProperty("os.name"));
ComboBox c = new ComboBox();
//c.setEditable(true);
primaryStage.setScene(new Scene(c));
primaryStage.show();
c.getItems().add("first");
c.getItems().add(null);
c.setConverter(new StringConverter<String>(){
#Override public String toString(String object) {
System.out.print("converting object: ");
if (object==null) {
System.out.println("null");
return "[none]";
}
System.out.println(object.toString());
return object.toString();
}
#Override public String fromString(String string) {
throw new RuntimeException("not required for non editable ComboBox");
}
});
}
}
And here it's the output, as you can see the true branch of the if (object==null) statement is never called. Is it a bug or a feature, and is it yet possible to customize null representation?
1.6.0_29-b11
2.2.3-b05
6.1
Windows 7
converting object: first
converting object: first
converting object: first
update
Adding a (just uncomment it):
c.setEditable(true);
I get another behavior, that is, clicking on the null item in the combo selection box, I get the method toString called, but the result is not presented in the selection box.
you can use setPromptText method to display "[None]" in comboBox if user make no choice.
Sample Code :
comboBox.setValue(null);
comboBox.setPromptText("[None]");
I've been learning the Weka API on my own for the past month or so (I'm a student). What I am doing is writing a program that will filter a specific set of data and eventually build a bayes net for it, and a week ago I had finished my discretization class and attribute selection class. Just a few days ago I realized that I needed to change my discretization function to supervised and ended up using the default Fayyad & Irani method, after I did this I began to get this error in my attribute selection class:
Exception in thread "main" weka.core.WekaException:
weka.attributeSelection.CfsSubsetEval: Not enough training instances with class labels (required: 1, provided: 0)!
at weka.core.Capabilities.test(Capabilities.java:1138)
at weka.core.Capabilities.test(Capabilities.java:1023)
at weka.core.Capabilities.testWithFail(Capabilities.java:1302)
at weka.attributeSelection.CfsSubsetEval.buildEvaluator(CfsSubsetEval.java:331)
at weka.attributeSelection.AttributeSelection.SelectAttributes(AttributeSelection.java:597)
at weka.filters.supervised.attribute.AttributeSelection.batchFinished(AttributeSelection.java:456)
at weka.filters.Filter.useFilter(Filter.java:663)
at AttributeSelectionFilter.selectionFilter(AttributeSelectionFilter.java:29)
at Runner.main(Runner.java:70)
My attribute selection before the change worked just fine, so I think that I may have done something wrong in my discretize class. My other part of this question relates to that, because I also noticed that my discretize class does not appear to really be discretizing the data; it's just putting all the numeric data into ONE range, not binning it strategically like the Fayyad & Irani should.
Here is my discretize class:
import weka.core.Instances;
import weka.filters.Filter;
import weka.filters.supervised.attribute.Discretize;
import weka.filters.unsupervised.attribute.NumericToNominal;
public class DiscretizeFilter
{
private Instances data;
private boolean sensitiveOption;
private Filter filter = new Discretize();
public DiscretizeFilter(Instances data, boolean sensitiveOption)
{
this.data = data;
this.sensitiveOption = sensitiveOption;
}
public Instances discreteFilter() throws Exception
{
NumericToNominal nm = new NumericToNominal();
nm.setInputFormat(data);
Filter.useFilter(data, nm);
Instances nominalData = nm.getOutputFormat();
if(sensitiveOption)//if the user wants extra sensitivity
{
String options[] = new String[1];
options[0] = options[0];
options[2] = "-E";
((Discretize) filter).setOptions(options);
}
filter.setInputFormat(nominalData);
Filter.useFilter(nominalData,filter);
return filter.getOutputFormat();
}
}
Here is my attribute selection class:
import weka.attributeSelection.BestFirst;
import weka.attributeSelection.CfsSubsetEval;
import weka.core.Instances;
import weka.filters.supervised.attribute.AttributeSelection;
public class AttributeSelectionFilter
{
public Instances selectionFilter(Instances data) throws Exception
{
AttributeSelection filter = new AttributeSelection();
for(int i = 0; i < data.numInstances(); i++)
{
filter.input(data.instance(i));
}
CfsSubsetEval eval = new CfsSubsetEval();
BestFirst search = new BestFirst();
filter.setSearch(search);
filter.setEvaluator(eval);
filter.setInputFormat(data);
AttributeSelection.useFilter(data, filter);
return filter.getOutputFormat();
}
public int attributeCounter(Instances data)
{
return data.numAttributes();
}
}
Any help would be greatly appreciated!!!
Internally Weka stores attribute values as doubles. It appears that an exception was thrown because every single instance in your dataset (data) is "missing a class", i.e. was given an internal class attribute value NaN ("not a number") for whatever reason. I would recommend to double-check if data's class attribute was created/set correctly.
I figured it out, it was my mistake of misunderstanding the description of the method "outputFormat()" in the Discretize class. I instead got the filtered instances from the useFilter() and that solved my problems! I was just giving the attribute selection filter the wrong type of data.
Trying to come up with a JUnit test for the following facade - I know this should be simple but I keep coming up blank. Any ideas to get me going in the right direction. It doesn't need to be complicated - I just need to get it done.
package business;
import domain.Items;
import services.exceptions.ItemNotFoundException;
import services.itemservice.IItemsService;
public class Itemmgr {
#SuppressWarnings("static-access")
public void store(Items item) {
Factory factory = Factory.getInstance(IItemsService.NAME);
IItemsService storeItem = (IItemsService)factory.getInstance(IItemsService.NAME);
storeItem.storeItem(item);
}
public void get(Items item) throws ClassNotFoundException, ItemNotFoundException {
Factory factory = Factory.getInstance(IItemsService.NAME);
#SuppressWarnings("static-access")
IItemsService getItem = (IItemsService)factory.getInstance(IItemsService.NAME);
try {
getItem.getItems("pens", 15, "red", "gel");
} catch (ClassNotFoundException | ItemNotFoundException e) {
e.printStackTrace();
System.out.println("Error - Class or Item Not Found");
}
}
}
As others have said, you could just write a unit test that first stores some Items, then in the same test, retrieve the Items and make sure that what you got back was "equivalent" to what you stored in the first place.
For instance (if I may venture a guess), it sounds to me like your Itemmgr class might be extended down the road to include volatile and persistent versions (maybe one version is in-RAM, maybe one is on-disk). Your test could go so far as to make sure that item1 == item2 returns true in the RAM-resident version, but item1 != item2 && item1.equals(item2) returns true in the persistent test to ensure that item2 was serialized or copied from somewhere and isn't just retrieving the original from a Map of some kind. Just some ideas.