I have one document template as like attached screen shot. now my requirement is i want to dynamically update some values of that document when i will upload it in alfresco site. i will either create that Document through node template or upload. I want to provide those values from document property page.
can anyone help me how can i achieve this.
I tried it using java script, but i am getting some problem. so i am thinking for using Alfresco CMIS API. But i am quite new in alfresco cmis. so can any one tell the better way which i can use for this task.
Thanks in advance.
I think you should trigger an custom action by a Rule
When someone update a node (for example by editing properties), your action will be triggered and you will be able to :
get the content of your node
get the properties of your node
use the apache poi library provided by alfresco (my guess is that you use word documents) to find your parameters, and the replace them by the value you find in the property nodes.
Here is an excellent tutorial to learn how to create a custom action.
Note : You may have to keep the original templated document if you want to change a second time your properties (by using versionning for example).
Edit (see discussion below) :
I assume you know how to use rules in alfresco : http://docs.alfresco.com/5.0/tasks/library-folder-rules-define.html
Declare a new action to assign to a rule. This action must be triggered when the excel is dropped or updated
Create an action implementing your need :
public class MyAction extends ActionExecuterAbstractBase {
...
#Override
protected void executeImpl(final Action arg0, final NodeRef arg1) {
// your code here
}
....
}
This action will :
Take the nodeRef parameter (which is the excel file) and load the file
...
Inputstream inputstream = getFileFolderService().getReader(arg1).getContentInputStream();
...
NPOIFSFileSystem fs = null;
HSSFWorkbook workbook = null;
try {
fs = new NPOIFSFileSystem(inputstream);
workbook = new HSSFWorkbook(fs.getRoot(), true);
//get your data with POI
For each row of your excel :
Make a copy of your template :
find it :
getSearchService().query(searchParameters)
copy it :
getFileFolderService().copy(sourceNodeRef, targetParentRef, newName)
Do transformations of your new word content (Find occurrences and replace with poi library).
Update the content of your new file :
ContentWriter writerDoc = getContentService().getWriter(document.getNodeRef(), ContentModel.PROP_CONTENT,
true);
writerDoc.putContent(file/inputStream);
In your context file, declare you action :
<bean id="my-action" class="x.y.z.MyAction" parent="action-executer">
<property name="searchService">
<ref bean="searchService" />
</property>
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="contentService">
<ref bean="contentService" />
</property>
<property name="fileFolderService">
<ref bean="FileFolderService" />
</property>
....
</bean>
In Share, assign to a folder a rule with the action you have created.
Related
I want configuration for show error messages on jsp using spring validator,but without using this configuration for message.properties.
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>message</value>
</list>
</property>
</bean>
error.rejectValue(String field,
String errorCode,
Object[] errorArgs,
String defaultMessage)
Register a field error for the specified field of the current object (respecting the current nested path, if any), using the given error description.
The field name may be null or empty String to indicate the current object itself rather than a field of it. This may result in a corresponding field error within the nested object graph or a global error if the current object is the top object.
Parameters:
field - the field name (may be null or empty String)
errorCode - error code, interpretable as a message key
errorArgs - error arguments, for argument binding via MessageFormat (can be null)
defaultMessage - fallback default message
reference link
Use
error.rejectvalue with three parameters("name of path variable" , "any name" , "message you want to show");
just like
error.rejectvalue("Name", "msg.name", "please enter name");
If I post in the format weather=sunny, Spring MVC happily converts this to an Weather enum instance using the enum with name=sunny.
However if I post weather=sunny&weather=windy, then Spring is not able to convert it into an instance of Weather[]. The error I get is:
Failed to convert property value of type 'java.lang.String[]' to required type 'com.blah.Weather[]' for property 'weather'
How can I achieve this?
You can use Converters to perform the custom conversion. For your example, you would need to do something like:
public class WeatherConverter implements Converter<String[], Weather[]> {
#Override
public Weather[] convert(String[] source) {
if(source == null || source.length == 0) {
return new Weather[0];
}
Weather[] weathers = new Weather[source.length];
int i = 0;
for(String name : source) {
weathers[i++] = Weather.valueOf(name);
}
return weathers;
}
}
You can use Converters anywhere you might want type-conversions. Now, what you need to do is register it:
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="package.path.WeatherConverter"/>
</list>
</property>
</bean>
And it is done.
You can see more details in the Spring Reference.
You could also look into PropertyEditors, with #InitBinder, and, probably, #ControllerAdvice if you want. However, Converters are much easier to use (IMO).
I am going to escape HTML in Spring MVC with Jackson Mapper to avoid XSS attack. I search for escaping with Jackson alone and how to config Jackson in Spring. I tried to export json with text like "<" ">", I expected it to escape them to < and >. For example, I added some text enclosed with "bold tag" <b>, I expected to see plain bold tag text in the front end html but it ended up so that the text is shown in bold style in the front end html page.
Below is my approach. I don't know why it didn't work out.
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
this.getJsonFactory().setCharacterEscapes(new CustomCharacterEscapes());
}
}
public class CustomCharacterEscapes extends CharacterEscapes {
private final int[] asciiEscapes;
public CustomCharacterEscapes() {
int[] esc = CharacterEscapes.standardAsciiEscapesForJSON();
esc['<'] = CharacterEscapes.ESCAPE_STANDARD;
esc['>'] = CharacterEscapes.ESCAPE_STANDARD;
esc['&'] = CharacterEscapes.ESCAPE_STANDARD;
esc['\''] = CharacterEscapes.ESCAPE_STANDARD;
asciiEscapes = esc;
}
#Override
public int[] getEscapeCodesForAscii() {
return asciiEscapes;
}
#Override
public SerializableString getEscapeSequence(int ch) {
return null;
}
}
Here is the Spring Bean configuration:
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<array>
<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<bean class="x.y.z.CustomObjectMapper" />
</property>
</bean>
</array>
</property>
</bean>
I have never tried to write my own HttpMessageConverter, but I did find this posting that seems pretty relevant to what you want to do. In looking at their solution vs. what you posted here, I can say the biggest differences I noticed was that you did not seem to implement/override the following:
protected boolean supports(Class<?> clazz), which indicates which class type you are supporting (I would recon in your case this would be Object or Serializable if you want it to be generic enough to handle every possibility, or some class specific to your domain objects)
protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage), looks like it's used for the request-side
protected void writeInternal(Object t, HttpOutputMessage outputMessage), which looks like it's used for the response-side
Another approach might be to simple create a custom Jackson serializer in conjunction with #ResponseBody. Or, better yet, if you have a value that is user-driven, and your storing it in a database, escape the values prior to insertion. That way you don't need to do anything at all, and the value(s) in question would be "safe" from end-to-end. If you wanted to get crazy-fancy, you could write a custom java.beans.PropertyEditor that escapes Strings for HTML and plug that into the mix using the InitBinder.
Finally, I would like to recommend that, instead of trying to replace the characters on your own, you use something like Apache Commons-Lang's StringEscapeUtils to escape the values.
I'm using Alfresco 4.0
I need to send email notification to selected members or all the members if a calendar event is created.
I'm a newbie.
Kindly help me, as I'm on a deadline.
You can set a simple rule on "Sites/yoursite/calendar" folder that executes a javascript script which sends the email.
If you need something more complicated then you can use alfresco's "onCreateNode" policy and bind it to "ia:calendarEvent" type.
From the top of my head something like this:
...
this.onCreateNode = new JavaBehaviour(this, "onCreateNode", NotificationFrequency.TRANSACTION_COMMIT);
this.policyComponent.bindClassBehaviour(QName.createQName(
NamespaceService.ALFRESCO_URI, "onCreateNode"),
"ia:calendarEvent", this.onCreateNode);
...
...
...
public void onCreateNode(ChildAssociationRef childAssocRef)
{
//send email here
}
Should roughly go like this:
Create a spring mananged bean, inject policyComponent
<bean id="calendarType" class="your.CalendarType"
init-method="init">
<property name="policyComponent" ref="policyComponent" />
</bean>
with methods:
public void init()
{
policyComponent.bindClassBehaviour(NodeServicePolicies.OnCreateNodePolicy.QNAME, CalendarModel.TYPE_EVENT ,
new JavaBehaviour(this, "onCreateNode"));
}
public void onCreateNode(ChildAssociationRef childAssocRef)
{
// do stuff here
}
Have a look at http://wiki.alfresco.com/wiki/Policy_Component for more details.
Thanks for all the valuable answers, I was able to complete my work on time. However after some search I got a complete script with all steps. You can follow this link, please read the 6th post for the answer:
https://forums.alfresco.com/en/viewtopic.php?f=47&t=42366
I have a question : suppose that in a spring MVC 3.0 enviroment i manage Views with Tiles : I have a xml file with definitions of all views. Every view extends a specific template. I have two templates : one for rendering a completeDOM () and one for partialDOM (.....).The problem is, there are some views that can be retrieved in fullDOM and also in partialDOM, but i don't want to write two similars definitions.
I was thinking to a dynamic approach : inject the template of a view at runtime, specifying an http parameter which should contains the name of the template. If the request contains the parameter, than Tiles should override the template exteded by the view, with the template detected by http parameter value.
Some suggestions?
I know this is an old question but I had needed to do this very thing so I thought I'd share my solution.
Tiles allows what they refer to as "runtime composition", which lets you modify definitions. So you can reuse an existing definition and just swap the template:
<tiles:insertDefinition name="existingDefinition" template="alternateTemplate.jsp" />
In spring tilesConfigurer you need to set mutable container:
<property name="useMutableTilesContainer" value="true"/>
<property name="checkRefresh" value="true"/>
And in your Spring Controller:
ModelAndView model = new ModelAndView();
MutableTilesContainer container = (MutableTilesContainer)ServletUtil.getContainer(request.getSession().getServletContext());
Attribute attribute = new Attribute("your template jsp");
HashMap<String, Attribute> attributes = new HashMap<String, Attribute>();
attributes.put("body", attribute);
Definition definition = new Definition("your definition name", "your jsp", attributes);
definition.setExtends("your definition template name");
definition = PatternUtil.replacePlaceholders(definition, "your definition name", new Object());
container.register(definition, request, response);
model.setViewName("your definition name");
I think a view preparer might help:
http://tiles.apache.org/framework/tutorial/advanced/preparer.html