Wicket image component not found on page - java

I get the following problem when trying to display a list of items. For each item, I have to display an image which is dynamically loaded via a Wicket WebResource. The items are loaded step by step — 50 at a time — upon user scrolling, using an Ajax scroll.
[ERROR] 2011-04-19 09:58:18,000 btpool0-1 org.apache.wicket.RequestCycle.logRuntimeException (host=, request=, site=):
org.apache.wicket.WicketRuntimeException: component documentList:scroller:batchElem:666:content:item:3:batchItemContent:linkToPreview:imageThumbnail not found on page com.webapp.document.pages.DocumentListPage[id = 1]
listener interface = [RequestListenerInterface name=IResourceListener, method=public abstract void org.apache.wicket.IResourceListener.onResourceRequested()]
org.apache.wicket.protocol.http.request.InvalidUrlException: org.apache.wicket.WicketRuntimeException: component documentList:scroller:batchElem:666:content:item:3:batchItemContent:linkToPreview:imageThumbnail
not found on page com.webapp.document.pages.DocumentListPage[id = 1] listener interface = [RequestListenerInterface name=IResourceListener, method=public abstract void org.apache.wicket.IResourceListener.onResourceRequested()]
at org.apache.wicket.protocol.http.WebRequestCycleProcessor.resolve(WebRequestCycleProcessor.java:262)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1310)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:545)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479)
at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByGuice$$51619816.CGLIB$doGet$6()
at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByGuice$$51619816$$FastClassByGuice$$6d42bf5d.invoke()
at com.google.inject.internal.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:64)
at com.freiheit.monitoring.PerformanceMonitoringMethodInterceptor.invoke(PerformanceMonitoringMethodInterceptor.java:115)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:64)
at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:44)
at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByGuice$$51619816.doGet()
at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:312)
at org.apache.wicket.protocol.http.WicketFilter$$EnhancerByGuice$$51619816.CGLIB$doFilter$4()
How can this problem be solved?
Here is the part of the code responsible for adding the image:
previewLink.add(createThumbnailSmall("imageThumbnail", documentModel));
in
createThumbnailSmall(final String id, final IModel<BaseDocument> documentModel) {
// thumbnailResource is an object that contains the path of the image
if (thumbnailResource != null) {
final WebResource resource = getWebResource(thumbnailResource);
final Image image = new Image(id, resource);
return image;
}
return new InvisibleContainer(id);
}
WebResource getWebResource(final DocumentResource documentResource) {
return new WebResource() {
private static final long serialVersionUID = 1L;
#Override
public IResourceStream getResourceStream() {
return new BaseStreamResource(documentResource);
}
};
}
where BaseStreamResource is the following:
public class BaseStreamResource extends AbstractResourceStream {
private InputStream _fileInputStream = null;
private DocumentResource _resource = null;
public BaseStreamResource(final DocumentResource documentResource) {
_resource = documentResource;
}
#Override
public InputStream getInputStream() throws ResourceStreamNotFoundException {
if (_fileInputStream == null) {
try {
if (_resource == null) {
throw new ResourceStreamNotFoundException("Resource was null");
}
_fileInputStream = _resource.getFileInputStream();
} catch (final ResourceNotAvailableException ex) {
throw new ResourceStreamNotFoundException(ex);
}
}
return _fileInputStream;
}
In HTML:
<a wicket:id="linkToPreview" href="#">
<img wicket:id="imageThumbnail" alt="Attachment"></img></a>

The code added hasn't really added any clues for me, but maybe I can help narrow it down a bit anyway.
The stacktrace includes a reference to com.webapp.document.pages.DocumentListPage, which is likely calling some of the code you've posted. The error indicates a bad url, so debugging into that class, adding debug prints, and looking at the values of any field containing a url might be worthwhile.
It might even help to modify the code in DocumentListPage (maybe temporarily for debugging) to catch org.apache.wicket.protocol.http.request.InvalidUrlException and adding debugging prints specifically when the exception is caught.
This isn't really an answer, but it's too big for a comment, and maybe it'll help you get closer to an answer.

The following solution solved the problem:
- extend WebResource class
- add extended class as a resource to application shared resources
Ex:
public class MyWebResource extends WebResource {
final ValueMap map = new ValueMap();
#Override
public IResourceStream getResourceStream() {
String fileName = getFileName();
File file = new File(basePath, fileName);
if (!file.exists()) {
LOG.error("File does not exist: " + file);
throw new IllegalStateException("File does not exist: " + file);
}
return new FileResourceStream(file);
}
public final void addResource() {
Application.get().getSharedResources().add(getClass().getName(), this);
}
protected String getFileName() {
return getParameters().getString("id");
}
public final String urlFor(final String fileName) {
final ResourceReference resourceReference = new ResourceReference(getClass().getName());
final String encodedValue = WicketURLEncoder.QUERY_INSTANCE.encode(fileName);
map.add("id", encodedValue);
final CharSequence result = RequestCycle.get().urlFor(resourceReference, map);
if (result == null) {
throw new IllegalStateException("The resource was not added! "
+ "In your Application class add the following line:"
+ "MyConcreteResource.INSTANCE.addResource()");
}
String absoluteUrl = RequestUtils.toAbsolutePath(result.toString());
return absoluteUrl;
}
}
In Application class, in init(), I have added MyWebResource to shared resources:
public void init() {
...
new MyWebResource().addResource();
...
}

Related

Refresh panel in Wicket with BootstrapDownloadLink

My problem is simple but I have no clue how to solve it. I have a feedbackPanel and I want to show an error message if the BootstrapDownloadLink fails. With a submit I could easily do:
protected void onSubmit(AjaxRequestTarget target) {
...
error("File_not_found"); //Wicket will print this on the feedback panel
target.add(getModalPanel().getFeedbackPanel()); //But i need to refresh it first
}
But the button is inside a panel which I fill with a populateItem and is the only way I know to insert Bootstrap Styles to it. The code of the button:
BootstrapDownloadLink downloadDocument = new BootstrapDownloadLink(IDITEMREPEATER, file) {
#Override
public void onClick() {
File file = (File)getModelObject();
if(file.exists()) {
IResourceStream resourceStream = new FileResourceStream(new org.apache.wicket.util.file.File(file));
getRequestCycle().scheduleRequestHandlerAfterCurrent(new ResourceStreamRequestHandler(resourceStream, file.getName()));
} else {
error(getString("error_fichero_no_existe"));
/// ???? need to refresh-> getModalPanel().getFeedbackPanel()
}
}
};
downloadDocument.setIconType(GlyphIconType.clouddownload);
downloadDocument.add(new AttributeModifier("title", getString("documentos.descargar")));
downloadDocument.add(new AttributeModifier("class", " btn btn-info negrita btn-xs center-block"));
downloadDocument.setVisible(Boolean.TRUE);
list.add(downloadDocument);
You could create or extend from an AjaxDownloadLink, for example like here.
The main idea is to have an AjaxBehavior that does the download, and you get a public void onClick(AjaxRequestTarget target) in which you can add the FeedbackPanel
downloadBehavior = new AbstractAjaxBehavior()
{
private static final long serialVersionUID = 3472918725573624819L;
#Override
public void onRequest()
{
[...]
ResourceStreamRequestHandler handler = new ResourceStreamRequestHandler(
AjaxDownloadLink.this.getModelObject(), name);
handler.setContentDisposition(ContentDisposition.ATTACHMENT);
getComponent().getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
}
};
And use that behavior in the onclick:
#Override
public void onClick(AjaxRequestTarget aTarget)
{
String url = downloadBehavior.getCallbackUrl().toString();
if (addAntiCache) {
url = url + (url.contains("?") ? "&" : "?");
url = url + "antiCache=" + System.currentTimeMillis();
}
// the timeout is needed to let Wicket release the channel
aTarget.appendJavaScript("setTimeout(\"window.location.href='" + url + "'\", 100);");
}
You can use target.addChildren(getPage(), IFeedback.class). This will add all instances of IFeedback interface in the page to the AjaxRequestTarget.
You can also use FeedbackPanel.class instead of the interface.
Or use getPage().visit(new IVisitor() {...}) to find a specific feedback panel if you don't want to add others which are not related.

Wanted but not invoke: Mockito PrintWriter

Hi I am working on a project and using PrintWriter class for opening and writing in the file. But when I am writing the test case for same it gives following error at Line 153
Wanted but not invoked:
mockPrintWriter.println("ID url1
");
-> at x.y.z.verify(ProcessImageDataTest.java:153)
Actually, there were zero interactions with this mock.
Code: (Uses Lombok Library)
ProcessImageData.java
#Setter
#RequiredArgsConstructor
public class ProcessImageData implements T {
private final File newImageDataTextFile;
#Override
public void execute() {
LineIterator inputFileIterator = null;
try {
File filteredImageDataTextFile = new File(filteredImageDataTextFilepath);
PrintWriter writer = new PrintWriter(newImageDataTextFile);
inputFileIterator = FileUtils.lineIterator(filteredImageDataTextFile, StandardCharsets.UTF_8.displayName());
while (inputFileIterator.hasNext()) {
if(someCondition)
**Line51** writer.println(imageDataFileLine);
//FileUtils.writeStringToFile(newImageDataTextFile, imageDataFileLine + NEWLINE, true);
}
}
} catch (Exception e) {
} finally {
LineIterator.closeQuietly(inputFileIterator);
**LINE63** writer.close();
}
}
ProcessImageDataTest.java
#RunWith(PowerMockRunner.class)
#PrepareForTest({ ProcessImageData.class, FileUtils.class, Printwriter.class })
public class ProcessImageDataTest {
private ProcessImageData processImageData;
private static final String FILTERED_IMAGE_DATA_TEXT_FILE_PATH = "filteredFilepath";
private File FILTEREDFILE = new File(FILTERED_PATH);
private static final File IMAGE__FILE = new File("imageFilePath");
private LineIterator lineIterator;
#Mock
private PrintWriter mockPrintWriter;
#Before
public void init() throws Exception {
MockitoAnnotations.initMocks(this);
processImageData = new ProcessImageData(Palettes_file, FILTERED_PATH, IMAGE_FILE);
PowerMockito.mockStatic(FileUtils.class);
PowerMockito.whenNew(PrintWriter.class).withArguments(IMAGE_FILE).thenReturn(mockPrintWriter);
PowerMockito.when(FileUtils.lineIterator(FILTERED_FILE, StandardCharsets.UTF_8.displayName())).thenReturn(lineIterator);
PowerMockito.when(lineIterator.hasNext()).thenReturn(true, true, false);
}
#Test
public void testTaskWhenIDInDBAndStale() throws IOException {
PowerMockito.when(lineIterator.nextLine()).thenReturn(ID2 + SPACE + URL1, ID1 + SPACE + URL2);
processImageData.execute();
List<String> exepctedFileContentOutput = Arrays.asList(ID2 + SPACE + URL1 + NEWLINE);
verify(exepctedFileContentOutput, 1, 1);
}
#Test
public void testTaskWhenIDNotInDB() throws IOException {
PowerMockito.when(lineIterator.nextLine()).thenReturn(ID2 + SPACE + URL1, ID3 + SPACE + URL2);
processImageData.execute();
List<String> exepctedFileContentOutput = Arrays.asList(ID3 + SPACE + URL2 + NEWLINE);
verify(exepctedFileContentOutput, 1, 1);
}
private void verify(List<String> exepctedFileContentOutput, int fileWriteTimes, int fileReadTimes) throws IOException {
for (String line : exepctedFileContentOutput){
**Line153** Mockito.verify(mockPrintWriter, Mockito.times(fileWriteTimes)).print(line);
}
PowerMockito.verifyStatic(Mockito.times(fileReadTimes));
FileUtils.lineIterator(FILTERED_IMAGE_DATA_TEXT_FILE, StandardCharsets.UTF_8.displayName());
}
}
I am mocking a new operator for PrintWriter also, injecting using beans. What is the mistake I am doing?? I am stuck on it from long time and not getting the error?
Any help is appreciated.
Updated :
I did changes suggested below and updated the code, but now I get the error:
Wanted but not invoked: mockPrintWriter.print("ASIN2 url1 "); ->
at softlines.ctl.ruleExecutor.tasks.ProcessImageDataTest.verify‌​(ProcessImageDataTes‌​t.java:153)
However, there were other interactions with this mock: -> at softlines.ctl.ruleExecutor.tasks.ProcessImageData.execute(Pr‌​ocessImageData.java:‌​51) ->
at softlines.ctl.ruleExecutor.tasks.ProcessImageData.execute(Pr‌​ocessImageData.java:‌​51) ->
at softlines.ctl.ruleExecutor.tasks.ProcessImageData.execute(Pr‌​ocessImageData.java:‌​58) –
I see 3 issues in your test:
You don't try to mock the correct constructor, indeed in the method execute, you create your PrintWriter with only one argument of type File while you try to mock the constructor with 2 arguments one of type File and the other one of type String.
So the code should rather be:
PowerMockito.whenNew(PrintWriter.class)
.withArguments(IMAGE_FILE)
.thenReturn(mockPrintWriter);
To be able to mock a constructor you need to prepare the class creating the instance which is ProcessImageData in this case, so you need to add ProcessImageData.class in the annotation #PrepareForTest. (I'm not sure ProcessImageDataTest.class is needed there)
The field lineIterator should be annotated with #Mock.
Instead of verifying print with a new line, you should verify directly println without new line it is much less error prone.
I simplified your code to show the idea.
Assuming that ProcessImageData is:
public class ProcessImageData {
private final File newImageDataTextFile;
public ProcessImageData(final File newImageDataTextFile) {
this.newImageDataTextFile = newImageDataTextFile;
}
public void execute() throws Exception{
try (PrintWriter writer = new PrintWriter(newImageDataTextFile)) {
LineIterator inputFileIterator = FileUtils.lineIterator(
newImageDataTextFile, StandardCharsets.UTF_8.displayName()
);
while (inputFileIterator.hasNext()) {
writer.println(inputFileIterator.nextLine());
}
}
}
}
My unit test would then be:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ProcessImageData.class, FileUtils.class})
public class ProcessImageDataTest {
private File file = new File("imageFilePath");
private ProcessImageData processImageData;
#Mock
private PrintWriter mockPrintWriter;
#Mock
private LineIterator lineIterator;
#Before
public void init() throws Exception {
MockitoAnnotations.initMocks(this);
processImageData = new ProcessImageData(file);
PowerMockito.whenNew(PrintWriter.class)
.withArguments(file)
.thenReturn(mockPrintWriter);
PowerMockito.mockStatic(FileUtils.class);
PowerMockito.when(
FileUtils.lineIterator(file, StandardCharsets.UTF_8.displayName())
).thenReturn(lineIterator);
PowerMockito.when(lineIterator.hasNext()).thenReturn(true, true, false);
}
#Test
public void testExecute() throws Exception {
PowerMockito.when(lineIterator.nextLine()).thenReturn("Foo", "Bar");
processImageData.execute();
Mockito.verify(mockPrintWriter, Mockito.times(1)).println("Foo");
Mockito.verify(mockPrintWriter, Mockito.times(1)).println("Bar");
}
}
For more details please refer to How to mock construction of new objects.
how can I add verification in unit test for writer.close?
One way could be to simply check that close() at be called once by adding the next line to your unit test:
Mockito.verify(mockPrintWriter, Mockito.times(1)).close();
Your construction of the PrintWriter doesn't match the mock. You told PowerMockito to return your mock like this:
PowerMockito.whenNew(PrintWriter.class).withArguments(IMAGE_FILE , StandardCharsets.UTF_8.name()).thenReturn(mockPrintWriter);
So you would have to say:
new PrintWriter(IMAGE_FILE, "UTF-8"); // 2 arguments
But instead in your execute method in the code that is being tested, you do:
PrintWriter writer = new PrintWriter(newImageDataTextFile); // only 1 argument
So you either need to change the PowerMockito withArguments clause, or you need to add "UTF-8" to the constructor invocation in the execute method.

SourcePollingChannelAdapter register bean

I dynamic create SourcePollingChannelAdapter. After add new url into db, i create new instance of SourcePollingChannelAdapter andd start it.
Here code:
public SourcePollingChannelAdapter getAdapter(RssStream rssStream) throws MalformedURLException {
String beanIdAdapter = "adapter." + rssStream.getId();
String beanIdSource = "source." + rssStream.getId();
SourcePollingChannelAdapter adapter;
if (context.containsBean(beanIdAdapter)) {
adapter = (SourcePollingChannelAdapter) context.getBean(beanIdAdapter);
}
else {
URL url = new URL(rssStream.getLink());
FeedEntryMessageSource source = new FeedEntryMessageSource(url, "news");
source.setApplicationContext(context);
source.setBeanName("source");
source.setBeanFactory(beanFactory);
source.afterPropertiesSet();
adapter = new SourcePollingChannelAdapter();
adapter.setApplicationContext(context);
adapter.setBeanName(beanIdAdapter);
adapter.setBeanFactory(beanFactory);
adapter.setSource(source);
adapter.setOutputChannel(channel);
adapter.setTrigger(new PeriodicTrigger(5000));
adapter.afterPropertiesSet();
}
return adapter;
}
But, after delete url from db, i need stop and delete SourcePollingChannelAdapter.
public void deleteAdapter(int id) {
final String beanId = "adapter." + id;
if (context.containsBean(beanId)) {
SourcePollingChannelAdapter adapter = (SourcePollingChannelAdapter) context.getBean(beanId);
adapter.stop(new Runnable() {
#Override
public void run() {
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
beanDefinitionRegistry.removeBeanDefinition(beanId);
}
});
}
}
I create new adaptar, start it and I try to delete. But i got NoSuchBeanDefinitionException. How to solve this problem?
You need to register the bean
if (beanFactory instanceof ConfigurableListableBeanFactory) {
((ConfigurableListableBeanFactory) beanFactory).registerSingleton(
beanIdAdapter, adapter);
}
Although the framework does so, you don't really need to register the source (unless you also need to access it later).
EDIT:
However, the framework is not really designed for this activity - it would be better to keep the references in your own class. See this note.

Image field as part of the FieldGroup in Vaadin7

I have a requirement to display the image as part of the FieldGroup. This is for the functionality where the Image appears as normal on a web page, when in edit mode I need to edit this image value by providing an 'upload' option.
I have a Pojo with a property of type com.vaadin.ui.Image along with the other String and Integer values.
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
I need to work this Image as a normal form element, for example when I edit a form, I have an editable TextField to type in the String value and change it, the same way I intend to display an upload button where I would have an option to replace the existing image.
I have tried using EasyUploads addon for this purpose by intercepting the build method of FieldGroup and specifying the Image field as of type org.vaadin.easyuploads.UploadField
Like this;
#Override
#SuppressWarnings({ "rawtypes", "unchecked" })
protected <T extends Field> T build(String caption, Class<?> dataType,
Class<T> fieldType) throws BindException {
T field = super.build(caption, dataType, fieldType);
if (caption.equalsIgnoreCase("image")) {
final UploadField imageField = new UploadField() {
#Override
protected void updateDisplay() {
final byte[] pngData = (byte[]) getValue();
String filename = getLastFileName();
String mimeType = getLastMimeType();
long filesize = getLastFileSize();
if (mimeType.equals("image/jpeg")) {
StreamSource imagesource = new ImageSource(pngData);
StreamResource resource = new StreamResource(
imagesource, "Uploaded File");
Embedded embedded = new Embedded("Image:" + filename
+ "(" + filesize + " bytes)", resource);
getRootLayout().addComponent(embedded);
} else {
super.updateDisplay();
}
}
};
imageField.setFieldType(FieldType.BYTE_ARRAY);
...
This however fails to display the already available image, errors out with the stacktrace:
Caused by: java.lang.IllegalArgumentException: Property type class com.vaadin.ui.Image is not compatible with UploadField
at org.vaadin.easyuploads.UploadField.setPropertyDataSource(UploadField.java:1021)
at com.vaadin.data.fieldgroup.FieldGroup.bind(FieldGroup.java:265)
at com.vaadin.data.fieldgroup.BeanFieldGroup.bind(BeanFieldGroup.java:167)
at com.vaadin.data.fieldgroup.FieldGroup.setItemDataSource(FieldGroup.java:106)
at com.vaadin.data.fieldgroup.BeanFieldGroup.setItemDataSource(BeanFieldGroup.java:142)
Is there a cleaner way of using an Image as part of the FieldGroup in vaadin 7?
I would suggest replacing in your Pojo the Image instance with a simple byte[], because looking through the UploadField code, I can't see any natural way of converting the result from the upload (which is either a byte[] or a File instance) into something else, using the FieldGroup like you asked.
If you look inside AbstractField.getValue(), you will see that the model value is eventually passed through a settable converter which would have normally helped you in this case (see com.vaadin.data.util.converter.Converter). But I think you are pretty much forced to use byte[] if you want to bind a image bean to the FieldGroup.
Anyway, if you DO replace with byte[] the following steps will help you:
Create a custom FieldGroupFieldFactory that will create an UploadField if you want to bind to a byte[] property + passes a ValueChangeListener for the UploadField is done uploading:
public class ImageEnhancedFieldFactory extends DefaultFieldGroupFieldFactory {
private Property.ValueChangeListener fileUploadedListener;
private ImageEnhancedFieldFactory(Property.ValueChangeListener fileUploadedListener) {
this.fileUploadedListener = fileUploadedListener;
}
#Override
public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {
if (byte[].class.equals(type)) {
UploadField uploadField = new UploadField(UploadField.StorageMode.MEMORY);
uploadField.setFieldType(UploadField.FieldType.BYTE_ARRAY);
uploadField.setButtonCaption("Change image");
uploadField.addListener(fileUploadedListener);
return (T) uploadField;
}
return super.createField(type, fieldType);
}
}
Create an Image instance that shows the content of the byte[] from the pojo:
final ImagePojo imagePojo = new ImagePojo();
imagePojo.setName("superman");
imagePojo.setImageContent(new byte[0]);
BeanItem<ImagePojo> item = new BeanItem<ImagePojo>(imagePojo);
final StreamResource imageResource = new StreamResource(new StreamResource.StreamSource() {
#Override
public InputStream getStream() {
return new ByteArrayInputStream(imagePojo.getImageContent());
}
}, "myimage");
imageResource.setCacheTime(0);
final Image image = new Image("Image", imageResource);
addComponent(image);
NOTE: its necessary to set the cache time to 0 in order to prevent the browser from caching the resource( see https://vaadin.com/book/vaadin7/-/page/components.embedded.html in the section Generating and Reloading Images)
3.Create the FieldGroup (with the new FieldGroupFieldFactory set) and bind to the properties of the pojo, including the one that contains the image content (the byte[]):
FieldGroup fieldGroup = new FieldGroup(item);
fieldGroup.setFieldFactory(new ImageEnhancedFieldFactory(new Property.ValueChangeListener() {
#Override
public void valueChange(Property.ValueChangeEvent event) {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
String filename = "myfilename-" + df.format(new Date()) + ".jpg";
imagePojo.setImageContent((byte[])event.getProperty().getValue());
image.markAsDirty();
imageResource.setFilename(filename);
}
}));
addComponent(fieldGroup.buildAndBind("Image name", "name"));
addComponent(fieldGroup.buildAndBind("Image content", "imageContent"));
I left a snippet on Gist of a component that you can paste in you UI and play around if you need (https://gist.github.com/gabrielruiu/9953279)

ICEFaces AJAX redirect to 404

EDIT: This occurs during any component AJAX call.
I am building a web application using ICEFaces 3.2.0 community along with Spring Security 3.2 Everything has been going very well up until a few days ago. I have an ACE AutoCompleteEntry component in the page with a backing bean attached to the value as the following example:
<ace:autoCompleteEntry id="autoCompleteState"
label="State"
labelPosition="top"
value="#{autoCompleteEntry.selectedText}"
rows="10" width="160"
filterMatchMode="startsWith">
<f:selectItems value="#{autoCompleteEntry.states}"/>
</ace:autoCompleteEntry>
The backing bean attached is as follows:
#ManagedBean(name=AutoCompleteEntry.BEAN_NAME)
#SessionScoped
public class AutoCompleteEntry implements Serializable {
public static final String BEAN_NAME = "autoCompleteEntry";
public static final String STATE_FILENAME = "State_Names.txt";
public static final String RESOURCE_PATH = "/resources/selectinputtext/";
public AutoCompleteEntry() {
}
public List<SelectItem> states;
public List<SelectItem> getStates() {
if(states == null) {
states = new ArrayList<SelectItem>();
for(String state : readStateFile()) {
states.add(new SelectItem(state));
}
}
return states;
}
private String selectedText = null;
public String getSelectedText() {return selectedText;}
public void setSelectedText(String selectedText) {this.selectedText = selectedText;}
private static List<String> readStateFile() {
InputStream fileIn = null;
BufferedReader in = null;
try {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
fileIn = ec.getResourceAsStream(AutoCompleteEntry.RESOURCE_PATH + STATE_FILENAME);
if(fileIn != null) {
in = new BufferedReader(new InputStreamReader(fileIn));
List<String> loadedStates = new ArrayList<String>(53);
String read;
while((read = in.readLine()) != null) {
loadedStates.add(read);
}
return loadedStates;
}
}catch (IOException failedRead) {
failedRead.printStackTrace();
}finally {
try {
if(in != null) {
in.close();
}
}catch (IOException failedClose) {
failedClose.printStackTrace();
}
}
List<String> errorReturn = new ArrayList<String>(1);
errorReturn.add("Error Loading State List");
return errorReturn;
}
}
The problem is that each time I attempt to test the component instead of bringing up a list of the States it redirects to an absolute path of my main page, which results in a 404. In developer tools I see an error of:
> Uncaught TypeError: Cannot read property 'value' of undefined
bridge.uncompressed.js.jsf:2701
namespace.onAfterUpdate.viewIDElement bridge.uncompressed.js.jsf:2701
apply bridge.uncompressed.js.jsf:122
(anonymous function) bridge.uncompressed.js.jsf:484
(anonymous function) bridge.uncompressed.js.jsf:363
(anonymous function) bridge.uncompressed.js.jsf:240
broadcast bridge.uncompressed.js.jsf:483
(anonymous function) bridge.uncompressed.js.jsf:1928
sendEvent jsf.js.jsf:1447
AjaxEngine.req.sendRequest jsf.js.jsf:1333
request jsf.js.jsf:1834
fullSubmit bridge.uncompressed.js.jsf:2309
submit bridge.uncompressed.js.jsf:2314
iceSubmit compat.uncompressed.js.jsf:1523
onclick
The developer tools log shows:
> [window] persisted focus for element "autoCompleteState_input"
bridge.uncompressed.js.jsf:1252
[window] full submit to localhost:8181/HHCA_Portal/pages/secure/HHCA.jsf
javax.faces.execute: #all
javax.faces.render: patientRecordsForm
javax.faces.source: autoCompleteState_input
view ID: v33tl98j
event type: unknown bridge.uncompressed.js.jsf:1252
XHR finished loading: "localhost:8181/HHCA_Portal/pages/secure/HHCA.jsf".
jsf.js.jsf:1334
AjaxEngine.req.sendRequest jsf.js.jsf:1334
request jsf.js.jsf:1834
fullSubmit bridge.uncompressed.js.jsf:2309
ice.ace.AjaxRequest ace-jquery.uncompressed.js.jsf:20854
ice.ace.ab ace-jquery.uncompressed.js.jsf:20779
ice.ace.Autocompleter.getUpdatedChoices autocompleteentry.js.jsf:695
ice.ace.Autocompleter.onObserverEvent autocompleteentry.js.jsf:637
(anonymous function)
I have spent many hours working on this and other issues, and I have run out of ideas. If someone has some kind of assistance I would really appreciate the help.
If you are using JSF 2 then you can add your own exception handler , this should be able to capture ajax requests.
<factory>
<exception-handler-factory>
test.MyExceptionHandlerFactory
</exception-handler-factory>
</factory>
see the examples here ,
http://balusc.blogspot.com/2012/03/full-ajax-exception-handler.html
http://wmarkito.wordpress.com/2012/04/05/adding-global-exception-handling-using-jsf-2-x-exceptionhandler/

Categories