How to fetch & update custom aspect property in 5.1.1 - alfresco

We have created custom property using custom content model.We need to fetch below information from the custom content model.
1)How can we fetch all Node Ref's which is having the cc:status property?
2)Lets say I will create new namespace[http://www.XXXX.co/model/copy-status/1.0] and new aspect name[cc:new-digeststatus].How can we update all old properties of cc:status to the different aspect name[cc:new-digeststatus] with different namespace?
<namespaces>
<namespace uri="http://www.custom.co/model/custom-status/1.0" prefix="cc"/>
</namespaces>
<aspects>
<aspect name="cc:digeststatus">
<title>Status</title>
<parent/>
<properties>
<property name="cc:status">
<title>status</title>
<type>d:text</type>
</property>
</properties>
</aspect>
</aspects>

Related

alfresco evaluator on custom component

I've made a component and I'd like to show that component on the document-details page only if the document has a certain aspect, so I tried to use an evaluator. I've added this bean in custom-slingshot-application-context.xml
<bean id="evaluator.doclib.metadata.hasInvoiceAspect"
parent="evaluator.doclib.action.propertyNotNull">
<property name="property" value="inv:invoice"/>
</bean>
In document-details.xml I added this
<component>
<region-id>custom-comp</region-id>
<sub-components>
<sub-component id="default">
<evaluations>
<evaluation>
<evaluators>
<evaluator type="evaluator.doclib.metadata.hasInvoiceAspect"/>
</evaluators>
<url>/components/custom/custom-comp</url>
</evaluation>
</evaluations>
</sub-component>
</sub-components>
</component>
I guess I've missed something as the component doesn't show up. I have 2 files named custom-slingshot, I tried both tomcat/shared/classes/alfresco/web-extension and tomcat/webapps/share/WEB-INF/classes/alfresco/web-extension.
Am I completely wrong with this? Is it possible to achieve what I want like that? How should I proceed?
There is a predefined evaluator to check whether a node has an aspect called evaluator.doclib.action.hasAspect. You simply need to create a bean with this evaluator as the parent and give an aspect to check against in the properties:
*added to some -context.xml in web-extension
<bean id="my.custom.evaluator" parent="evaluator.doclib.action.hasAspect">
<property name="aspects">
<list>
<value>my:hasInvoiceAspect</value>
</list>
</property>
</bean>
Then you'll reference that bean in your DocLibActions config added to *extension-modules.xml (web-extension/site-data/extensions)...
<config condition="DocLibActions" evaluator="string-compare">
<actions>
<action...>
<!-- Custom evaluator -->
<evaluator>my.custom.evaluator</evaluator>
</action>
</actions>
</config>
Voila.
More info on predefined evaluators.
Good sample project here.

Associate multiple properties in advanced search in Alfresco

I've successfully added a custom form to the advanced search interface in Alfresco, but I'm facing a problem. Here's my custom form (search-config-custom.xml):
<config evaluator="model-type" condition="cv:document">
<forms>
<form id="search">
<field-visibility>
<show id="cv:appl_name" />
<show id="cv:appl_surn" />
<show id="cv:appl_phone" />
<show id="cv:appl_lang_1" />
<show id="cv:appl_level_1" />
<show id="cv:appl_lang_2" />
<show id="cv:appl_level_2" />
<show id="cv:appl_lang_3" />
<show id="cv:appl_level_3" />
</field-visibility>
</form>
</forms>
</config>
The form is basically querying information regarding job applicants. Applicants can enter up to three foreign languages in their profile, and assign a level of proficiency to them.
Now, here's the problem: let's say a recruiter wants to search for candidates with a high level of Spanish. As I have my form now, they would have to enter "Spanish" in the three language fields in order to get reliable results, as it's not known beforehand the order in which candidates entered their languages, if any.
So, I'm looking for a way to have a field that can automatically search across all the different language fields, so that instead of having "Language 1", "Language 2" and "Language 3", I can simply have "Languages" as a single search field. Then, language fields should be associated with their respected levels, and I really don't know how to do this.
Here's the content model the custom search form is querying:
<types>
<type name="cv:document">
<title>Job Application</title>
<parent>cm:content</parent>
<properties>
<property name="cv:appl_name">
<title>Applicant's first name</title>
<type>d:text</type>
</property>
<property name="cv:appl_surn">
<title>Applicant's last name</title>
<type>d:text</type>
</property>
<property name="cv:appl_phone">
<title>Applicant's phone number</title>
<type>d:text</type>
</property>
<property name="cv:appl_lang_1">
<title>Language 1</title>
<type>d:text</type>
</property>
<property name="cv:appl_level_1">
<title>Level for Language 1</title>
<type>d:text</type>
</property>
<property name="cv:appl_level_2">
<title>Level for Language 2</title>
<type>d:text</type>
</property>
<property name="cv:appl_level_3">
<title>Level for Language 3</title>
<type>d:text</type>
</property>
</properties>
</type>
</types>
I'm running Alfresco 5.0.0.
You could edit your SOLR schema to add a new SOLR field which would be filled with all languages. Then you'd query against that single field.
For example.
<field name="all" type="text___" indexed="true" omitNorms="false" stored="false" multiValued="true" />
<copyField source="*" dest="all" />

How to use VelocityLayoutViewResolver in spring-webmvc with velocity

<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
<property name="prefix" value="" />
<property name="suffix" value=".vm"></property>
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="layoutUrl" value="layout/default.vm" />
</bean>
how the key word "layoutUrl" work in VelocityLayoutViewResolver?
Its very common to have a dynamic web page divided into a layout part and a content part. The layout part might consist of a header, a footer, a sidebar, a navigation and so on. Elements meant to look more or less the same on every response, that is. But the content part differs, because that's where the action goes on, right?
Layout and content should be kept apart in different .vm files, so that the layout has to be designed (and changed) only once and the content part doesn't have to repeat anything.
The question is how to put those two parts together on each response. One approach is to parse the layout file in every content file. But as the layout usually wraps the content this very likely leads to more than one parsed layout file per content file.
A better way is to reverse that and to merge the content into the layout. This is way easier to handle. All you have to do is to declare a .vm file to work as the general layout file. In this file you put a var named $screen_content and magically the view you returned in your controller at a certain request is blended in at that spot.
Your layoutUrl property tells path and file name of your layout file relative to the resourceLoaderPath you have declared in this bean
<bean
id="velocityConfig"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<beans:property name="resourceLoaderPath" value="/WEB-INF/templates/" />
</bean>
Following your example...
<bean
id="viewResolver"
class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
...
<property name="layoutUrl" value="layout/default.vm" />
</bean>
...your layout file has to be /WEB-INF/templates/layout/default.vm

How to properly configure Spring.NET in a web context

I'm having a bit of a problem keeping values from appearing in scope for all users. I'm not sure what exactly I may be doing wrong, but I'm at wits end. I'm thinking either I have my container objects scoped wrong or I'm passing the values along the WebContext. First, here's what I'm doing in code. This works, but it's showing details for the first user who logs into the site (note: my PageStore is just a property of type IDictionary that stores values to share to all user controls on the page):
using (BasePage page = (BasePage)(Spring.Web.UI.Page)this.Context.Handler) {
if ((page.PageStore("LoginId") != null)) {
this.Model.LoginId = Convert.ToString(page.PageStore("LoginId"));
}
}
Second, I've tried different scopes for my objects but I'm coming up empty. Here is how my objects are currently configured in the container:
Snippet of my business tier configuration
<!-- Transaction Management Strategy - local database transactions -->
<object id="transactionManager"
type="Spring.Data.Core.AdoPlatformTransactionManager, Spring.Data" scope="request">
<property name="DbProvider" ref="MyProvider"/>
</object>
<tx:attribute-driven transaction-manager="transactionManager" />
<!-- Data Access Objects -->
<object id="DataAccess" type="MyApp.Business.DataAccess.DataAccess, MyApp.Business.DataAccess" abstract="true" scope="request">
<property name="AdoTemplate" ref="MyTemplate" />
</object>
<object id="ManagerDAO" type="MyApp.Business.DataAccess.ManagerDAO, MyApp.Business.DataAccess" parent="DataAccess" scope="request">
<property name="TableName" value="vw_managers" />
<property name="IsAllowedDeletion" value="False" />
<property name="IsAllowedUniqueIdRetrieval" value="False" />
</object>
<!-- Services -->
<object id="SearchService" type="MyApp.Business.Services.SearchService, MyApp.Business.Services" scope="request">
<property name="ManagerDAO" ref="UserDAO" />
</object>
Snippet of my presentation layer:
<object id="BasePageModel" type="MyApp.Presentation.Models.BasePageModel, MyApp.Presentation" abstract="true" scope="session"/>
<object id="ManagerModel" type="MyApp.Presentation.Models.ManagerModel, MyApp.Presentation" parent="BasePageModel" scope="session"/>
<!-- Presenters-->
<object name="ManagerPresenter" type="MyApp.Presentation.Presenters.ManagePresenter, MyApp.Presentation" singleton="false" scope="session">
<property name="SearchSvc" ref="SearchService"/>
</object>
Snippet of my UI layer objects:
<!-- Pages -->
<object id="BasePage" type="MyApp.UI.BasePage, MyApp.UI" abstract="true" singleton="false" scope="session" />
<object id="StandardPage" parent="BasePage" abstract="true" singleton="false" scope="session">
<property name="MasterPageFile" value="~/Layouts/Site.master"/>
</object>
<object type="~/Pages/Manager.aspx" parent="StandardPage" singleton="false" scope="session"/>
I know there are 100 ways to skin this cat, but the fastest solution is to just get this configured properly and drive on. Is my configuration flaky or am I going about this all wrong?
Edit: Common sense is starting to kick in....IDictionary isn't thread safe.
Fixed my problem. Switched my Dictionary objects to thread safe ConcurrentDictionary objects and fixed my scoping issues. For the scopes, my business tier objects are singletons, my model objects are in the session scope, and my views(user controls) and pages are now set to the request scope, non-singletons.

Alfresco Share not showing subtype or custom type

I have a custom model called "medicalBill" that inherits from another custom model called "clientDocument". For some reason in the share UI only the "clientDocument" is visible in the change type dialog. I have read that in the change type dialog it only shows models that are subtypes of cm:content. Does that mean ONLY direct subtypes?
I have this in my share-config-custom.xml is it not possible to have a subtype of a subtype here.
<types>
<type name="cm:content">
<subtype name="cd:clientDocument">
<subtype name="mb:medicalBill"/>
</subtype>
</type>
<type name="cm:folder">
</type>
</types>
Edit: I am running alfresco 3.4d on jboss under linux.
Depending on which version of Alfresco you're using, the Change Type dialog in Share is configured differently
Alfresco < 3.4
You need to override the default configuration
Alfresco >= 3.4
You need to place the configuration in (e.g.) share-config-custom.xml
Regardless of the approach, the configuration will look like the following:
<type name="my:sourceType">
<subtype name="my:targetType1"/>
<subtype name="my:targetType2"/>
...
</type>
Where you specify which types are available for selection in the drop down (my:targetType*) depending on the type of the content you're acting on (my:sourceType).
As subtype elements cannot be nested, you have to specify all the possible type changes as sibling elements. As long as the source type is an ancestor type of the target type, everything should work as expected. To stick with your example:
<types>
<type name="cm:content">
<subtype name="cd:clientDocument" />
<subtype name="mb:medicalBill" />
</type>
<type name="cm:folder">
</type>
</types>
If you also need to show mb:medicalBill in the change type dropdown for cd:clientDocument documents you need to add another <type name="cd:clientDocument>..." element in the XML

Resources