Jackrabbit - why does search excerpt contain all node properties concatenated? - lucene

When I perform a jackrabbit (version 2.2.9) search and I call get row.getValue("rep:excerpt()") the returned string is just all the properties (excluding jcr: properties) concatenated. How do I control this? eg. If I have a property called "description" containing "bla foo bla" when I search for "foo" I would like to see rep:excerpt() return part of just the description.
I tried creating an index config (and I deleted my repository between tests) in an attempt to control what properties were indexed, to no avail.
Workspace.xml...
<SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
<param name="path" value="${wsp.home}/index"/>
<param name="supportHighlighting" value="true"/>
<param name="excerptProviderClass" value="org.apache.jackrabbit.core.query.lucene.DefaultHTMLExcerpt"/>
<param name="indexingConfiguration" value="${wsp.home}/indexing_configuration.xml"/>
</SearchIndex>
indexing_configuration.xml
<?xml version="1.0"?>
<!DOCTYPE configuration SYSTEM "http://jackrabbit.apache.org/dtd/indexing-configuration-1.0.dtd">
<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
<index-rule nodeType="nt:teneoNode">
<property>description</property>
<property>input</property>
<property>key</property>
<property>comment</property>
</index-rule>
</configuration>
Thanks.
Ted.

You can configure the ExcerptProvider (Javadoc) implementation which is responsible for the rep:excerpt() functionality in the SearchIndex element of you workspace.xml file:
<param name="excerptProviderClass" value="org.apache.jackrabbit.core.query.lucene.DefaultHTMLExcerpt"/>
You might need to plugin in your own implementation for you specific needs.
There is also some - unfortunately rather old - information on the Jackrabbit Wiki.

Related

Sulu: how to query custom entity type?

I have defined custom entity type "matches" and it is back-end editable, everything works as expected.
Now I need a way to query content in that type. Can smart content field type do that? I expected that xml like this would do the trick:
<property name="matches" type="smart_content">
<!-- #see https://docs.sulu.io/en/2.2/reference/content-types/smart_content.html -->
<meta>
<title lang="en">Matches</title>
<title lang="de">Streichhölzer</title>
</meta>
<params>
<param name="provider" value="lists"/>
<param name="types" value="matchevents"/>
<param name="max_per_page" value="5"/>
<param name="page_parameter" value="m"/>
</params>
</property>
But that didn't help. Can it be done with "smart_content" field type? I yes - how? If no - what would be the best way to achieve that?
you have to create a custom DataProvider for your entity and then use your provider in the xml-definition.
So you have to create a repository which implements the DataProviderRepositoryInterface. This repository is used to query the entity.
Furthermore you also have to create the actual dataprovider service. This class should extend form the BaseDataProvider and finally you have to make the service definition with the tag sulu.smart_content.data_provider and an alias.
The alias is used in the xml-file e.g.
<property name="matches" type="smart_content">
<meta>
<title lang="en">Matches</title>
<title lang="de">Streichhölzer</title>
</meta>
<params>
<param name="provider" value="myCustomDataProviderAlias"/>
</params>
</property>
Check out the documentation for a step by step tutorial on how to create a custom data provider. https://docs.sulu.io/en/2.2/cookbook/smart-content-data-provider.html#how-to-create-a-custom-dataprovider

create sitecore item as pdf

Hi i am doing kind of migrating other cms to sitecore now.
So my requirement is to viewing pdf in the respective url..
Existing site url : DOMAIN.COM/pressrelease/one
And this will show PDF content in a browser.
New site expected Url: NEWDOMAIN.COM/pressrelease/one
Similarly on my sitecore content i try to create under root one pressrelease item and its child is one.pdf. But i cant able to view my pdf after this when i gave url like NEWDOMAIN.COM/pressrelease/one.
And need expected behaviour is to open a pdf file in a browser as like media (/-/media/pressrelease/one)items are can able to view.
Create AllowedExtensions.config in App_config/include folder(if it does not exist already) and add the following sitecore configuration.The configuration makes sure that pdfs are allowed via URL.
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<preprocessRequest>
<processor type="Sitecore.Pipelines.PreprocessRequest.FilterUrlExtensions, Sitecore.Kernel">
<param desc="Allowed extensions (comma separated)">aspx, ashx, asmx, xml, txt,pdf,png</param>
<param desc="Blocked extensions (comma separated)">*</param>
<param desc="Blocked extensions that stream files (comma separated)">*</param>
<param desc="Blocked extensions that do not stream files (comma separated)"/>
</processor>
</preprocessRequest>
</pipelines>
</sitecore>
</configuration>
I have solved my case using below solution
First i have created one content item NEWDOMAIN.COM/pressrelease/one.
This item having two fields from my template, like shown below.
Then i have some separate Layout file for this content item, In the Layout i have created the code for displaying pdf.(Also in some Layouts i can able to download file too using this approach.)
if(mediaResult.mediaItem != null)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = mediaResult.mediaItem.MimeType;
HttpContext.Current.Response.AppendHeader("Content-Disposition", string.Format("inline;filename=\"{0}\"", mediaResult.mediaName));
HttpContext.Current.Response.StatusCode = (int)HttpStatusCode.OK;
HttpContext.Current.Response.BufferOutput = true;
// Copy the media stream to the response output stream
mediaResult.mediaItem.GetMediaStream().CopyTo(HttpContext.Current.Response.OutputStream);
// As momma always said: Always remember to flush
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}

Using pcl_to_scan without OpenNI to convert PointCloud into LaserScan

I'm working on a project that uses Kinect for robot navigation. We use ROS Groovy as distro and Gazebo for simulation, and have sensor and model plugins for the robot model. We have manipulated kinect model using the .sdf file and added libgazebo_ros_openni_kinect.so file as plugin. So now, whenever we launch the robot model in Gazebo, it publishes topics like these: /cam3d/depth/image_raw, /cam3d/depth/points, /cam3d/rgb/image_raw ...
Our model.sdf contains this part for the kinect model:
<plugin name="kinect" filename="libgazebo_ros_openni_kinect.so" >
<alwaysOn>true</alwaysOn>
<updateRate>10</updateRate>
<pointCloudCutoff>0.001</pointCloudCutoff>
<imageTopicName>/cam3d/rgb/image_raw</imageTopicName>
<pointCloudTopicName>/cam3d/depth/points</pointCloudTopicName>
<cameraInfoTopicName>/cam3d/camera_info</cameraInfoTopicName>
<depthImageTopicName>/cam3d/depth/image_raw</depthImageTopicName>
<depthImageInfoTopicName>/cam3d/depth/camera_info</depthImageInfoTopicName>
<frameName>kinect</frameName>
<distortion_k1>0.00000001</distortion_k1>
<distortion_k2>0.00000001</distortion_k2>
<distortion_k3>0.00000001</distortion_k3>
<distortion_t1>0.00000001</distortion_t1>
<distortion_t2>0.00000001</distortion_t2>
<imageTopicName>kinectimage</imageTopicName>
<pointCloudTopicName>pcloud</pointCloudTopicName>
<depthImageTopicName>depth</depthImageTopicName>
<depthImageCameraInfoTopicName>depthcamerainfo</depthImageCameraInfoTopicName>
</plugin>
We intend to use pcl_to_scan package in order to convert the point cloud data into LaserScan. I've done a little research about it. People say that I have to create a launch file to use the pcl_to_scan package. I took a look at the example launch files and realized that they use openni.launch and openni_manager in order to convert /camera/depth/points into laserscan data. I need to manipulate that launch file in order to work with the model that we have created, since we're not using openni at the moment.
The launch file that they offer is like this:
<launch>
<!-- kinect nodes -->
<include file="$(find openni_launch)/launch/openni.launch"/>
<!-- openni_manager -->
<node pkg="nodelet" type="nodelet" name="openni_manager" output="screen" respawn="true" args="manager"/>
<!-- throttling -->
<node pkg="nodelet" type="nodelet" name="pointcloud_throttle" args="load pointcloud_to_laserscan/CloudThrottle openni_manager">
<param name="max_rate" value="2"/>
<remap from="cloud_in" to="/camera/depth/points"/>
<remap from="cloud_out" to="cloud_throttled"/>
</node>
<!-- fake laser -->
<node pkg="nodelet" type="nodelet" name="kinect_laser" args="load pointcloud_to_laserscan/CloudToScan openni_manager">
<!--Setting the parameters for obtaining scan data within desired ranges-->
<param name="max_height" value="0.30"/>
<param name="min_height" value="-0.15"/>
<param name="angle_min" value="-0.5233"/>
<param name="angle_max" value="0.5233"/>
<param name="range_min" value="0.50"/>
<param name="range_max" value="6.0"/>
<param name="output_frame_id" value="/camera_depth_frame"/>
<remap from="cloud" to="cloud_throttled"/>
</node>
</launch>
I've also stumbled into depthimage_to_laserscan and pointcloud_to_laserscan packages, that can also be useful for dealing with this issue. Any help regarding the pcl_to_scan issue, or any other easier methods to deal with this situation will be greately appreciated. Thanks in advance.

What are the "allowedTypes" for .rar file (interceptor "fileUpload") in struts2?

<package name="my-default" extends="struts-default" namespace="/">
<interceptors>
<interceptor-stack name="globalInterceptor">
.....
<interceptor-ref name="fileUpload">
<param name="maximumSize">1048576</param>
<param name="allowedTypes">application/x-rar-compressed</param>
</interceptor-ref>
.....
</interceptor-stack>
</interceptors>
....
</struts>
I want to mine type for .rar file in struts2 which interceptor "fileUpload", but when I define "allowedTypes" which "application/x-rar-compressed", It doesn't work.
How can I resolve this?
These are the allowed type values -
image/gif,image/jpeg,image/png,image/bmp,application/msword,text/plain,application/pdf,application/ms-excel,application/vnd.ms-excel,image/bitmap
Rar and zip are not one of them.
The MIME type is set by your browser, and this (specially for a .rar file type, not so popular as others) is not fully previsible - I suspect it can vary from browser to browser. If want to play safe, you can omit the allowedTypes option and do the check programatically in your action. Perhaps you'll want also (not as an alternative, but as an complementary check) to check the file extension in the client side, with Javascript.
try
<param name="allowedExtensions ">rar</param>

Simulating the Maven2 filter mechanism using Ant

I have a properties file, let say my-file.properties.
In addition to that, I have several configuration files for my application where some information must be filled regarding the content of my-file.properties file.
my-file.properties:
application.version=1.0
application.build=42
user.name=foo
user.password=bar
Thus, in my configuration files, I will find some ${application.version}, ${user.name} that will be replaced by their value taken in the properties file...
When I build my application using Maven2, I only need to specify the properties file and say that my resources files are filtered (as in this answer to another problem). However, I need to achieve the same thing by using only Ant.
I've seen that Ant offers a filter task. However, it forces me to use the pattern #property.key# (i.e. #user.name# instead of #{user.name}) in my configuration files, which is not acceptable in my case.
How can I solve my problem?
I think expandproperties is what you are looking for. This acts just like Maven2's resource filters.
INPUT
For instance, if you have src directory (one of many files):
<link href="${css.files.remote}/css1.css"/>
src/test.txt
PROCESS
And in my ANT build file we have this:
<project default="default">
<!-- The remote location of any CSS files -->
<property name="css.files.remote" value="/css/theCSSFiles" />
...
<target name="ExpandPropertiesTest">
<mkdir dir="./filtered"/>
<copy todir="./filtered">
<filterchain>
<expandproperties/>
</filterchain>
<fileset dir="./src" />
</copy>
</target>
</project>
build.xml
OUTPUT
*When you run the ExpandPropertiesTest target you will have the following in your filtered directory: *
<link href="/css/theCSSFiles/css1.css"/>
filtered/test.txt
You can define a custom FilterReader. So you have a couple of choices:
Extend/copy the org.apache.tools.ant.filters.ReplaceTokens class and define a Map property that references another properties file containing all the replacements. This is still a bit of a chore as you have to define all the replacements.
Extend/copy the org.apache.tools.ant.filters.ReplaceTokens class with additional processing that just substitutes the matched token with a version with the correct garnish. Of course you'd have to be really careful where you use this type as it will match anything with the begin and end token.
So in the read() method of ReplaceTokens, replace:
final String replaceWith = (String) hash.get(key.toString());
with a call to a getReplacement() method:
...
final String replaceWith = getReplacement(key.toString);
...
private String getReplacement(String key) {
//first check if we have a replacement defined
if(has.containsKey(key)) {
return (String)hash.get(key);
}
//now use our built in rule, use a StringBuilder if you want to be tidy
return "$" + key + "}";
}
To use this, you'd ensure your class is packaged and on Ant's path and modify your filter:
<filterreader classname="my.custom.filters.ReplaceTokens">
<!-- Define the begin and end tokens -->
<param type="tokenchar" name="begintoken" value="$"/>
<param type="tokenchar" name="endtoken" value="}"/>
<!--Can still define explicit tokens, any not
defined explicitly will be replaced by the generic rule -->
</filterreader>
One hooooooorible way to make this work, inspired by the solution of Mnementh, is with the following code:
<!-- Read the property file -->
<property file="my-file.properties"/>
<copy todir="${dist-files}" overwrite="true">
<fileset dir="${src-files}">
<include name="*.properties"/>
</fileset>
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
<!-- Define the begin and end tokens -->
<param type="tokenchar" name="begintoken" value="$"/>
<param type="tokenchar" name="endtoken" value="}"/>
<!-- Define one token per entry in the my-file.properties. Arggh -->
<param type="token" name="{application.version" value="${application.version}"/>
<param type="token" name="{user.name" value="${user.name}"/>
...
</filterreader>
</filterchain>
</copy>
Explanations:
I am using the ReplaceTokens reader to look for all $...} pattern. I cannot search for ${...} patterns, as the begintoken is a char and not a String. Then, I set the list of tokens starting with a { (i.e. I see {user.name instead of user.name). Hopefully, I have "only" about 20 lines in my-file.properties, so I need to define "only" 20 tokens in my Ant file...
Is there any simple and stupid solution to solve this simple and stupid problem??
Ant knows a concept named Filterchains, that is useful here. Use the ReplaceTokens-filter and specify the begintoken and endtoken as empty (normally that's '#'). That should do the trick.