Powered By Blogger

Thursday, February 24, 2011

How Javascript integrated with Java

Alfresco JavaScript Debugger

The Alfresco Server provides a built-in server-side JavaScript debugger which allows line by line step through, variable inspection and arbitrary script execution.

Note:

* The debugger executes in the Java VM of the Alfresco Server. It must be executed on the same machine as the Alfresco Server - remote debugging is not supported.
* The debugger does not function correctly on early SunJDK1.6 series JVMs - enabling it will crash the entire JVM.

To enable and disable the JavaScript debugger use the following URL (you must be logged in as an administrator):

http://:/alfresco/service/api/javascript/debugger

This URL displays the current status of the debugger and allows you toggle between enabled and disabled.

When enabled, the JavaScript Debugger window is displayed. Upon execution of any server-side JavaScript, the debugger will intercept and stop execution at the first JavaScript statement. You can then step through, view variables etc or resume execution. When disabled, server-side JavaScript is executed without interruption.


How is Scripting integrated into Alfresco?

The Script Service is a typical Alfresco repository service accessed via a Spring managed bean with the name of ScriptService.

Only developers will be interested in accessing the ScriptService directly, those more interested in simply writing scripts themselves should skip this section and jump to Scripting API.

The available scripting engines can be configured in the Alfresco Spring config file script-services-context.xml. You should download the Alfresco SDK to examine the structure of this file.

As of Alfresco 2.1 a mechanism for adding additional scripting engines has been available. It is possible to completely replace or augment the existing JavaScript implemenation with others such as PHP or Ruby. The correct script engine implementation will be automatically selected by the ScriptService when executing a script based on the file extension of the script being executed. If it cannot resolve the engine to use, then the developer can specify it explicitly when calling the ScriptService.

Further engines can be added by developers. Examining the script-services-context.xml for configuration examples. The engine must implement org.alfresco.service.cmr.repository.ScriptProcessor interface and it is recommend to extend the org.alfresco.repo.processor.BaseProcessor abstract class and override the various execute() methods.

A Java based PHP engine has been integrated and is a good example of this, it is available as an AMP download for addition into an existing Alfresco installation.


Adding Custom Script APIs

It is possible to create and add custom script API's implemented in Java and accessible as root objects in JavaScript. This provides an integration point for Alfresco extensions to provide custom API's where appropriate.

In order to implement a custom JavaScript API it is recommended that you develop a POJO (Plain Old Java Object) that extends the base class org.alfresco.repo.processor.BaseProcessorExtension. The public methods of your class will be those that will be accessable from JavaScript. (For example see org.alfresco.repo.jscript.ScriptLogger).

Once complete, you must then configure your bean in Spring. Make use of the baseJavaScriptExtension parent bean definition in order to ensure your object is automatically registered with the ScriptService framework. The name of the object as it will appear to script writers must also be specified in the bean definition.

The following example shows the bean definition for the ScriptLogger custom API.



logger



Since this is a standard Spring bean definition any additional services that are required can be injected as properties into the bean definition in the usual way.

Once this bean have been loaded the custom API object will be accessible directly in JavaScript by calling the public methods on the named object. For example the following shows how the log method can be called on the logger API we have defined above.

...
logger.log("This is a log message.");
...


Native Java API Access

In some cases you may find that you're unable to satisfy a requirement using the Javascript API, but that a Java API (perhaps the Alfresco Foundation Services API or AVMService for our WCM module) contains facilities that would allow you to do so.

Using the method described in Adding Custom Script APIs, it is possible to add additional root scope objects to Javascript. In the case of the Alfresco Foundation Services API the only object that needs to be injected is the ServiceRegistry (or a proxy of it) - an example implementation of this may be found at Configuring the ServiceRegistry as a Javascript Root Object.

As of Alfresco 2.1.3, Javascript scripts stored in the classpath (e.g. in the file system at the extension directory) can also leverage the Rhino Javascript interpreter's native Java integration facilities (see the Rhino documentation for more details).

However, for security reasons these mechanisms are completely disabled for Javascript scripts that are stored in the repository. This means that the Javascript file has to be stored in the filesystem to be able to access the Native Java API.

Note that there are some important things to keep in mind when calling native Java APIs from Javascript:

* Mixing the standard JavaScript APIs and Alfresco Java APIs is not recommended - the JavaScript API caches some values which may not be reflected when using Java APIs and vice-versa.
* Extreme care must be taken when using certain Alfresco APIs, for example the transaction APIs. This is because in many cases the Alfresco scripting framework includes logic that handles some of these "plumbing" concerns automatically - for example the Javascript script for a Web Script is automatically executed within an Alfresco transaction - programmatic transaction handling within the Javascript is not required and may interfere with the default behaviour.
* Native Java collections (Arrays, Maps, Lists etc.) do not get translated into their Javascript equivalents, so you cannot use Javascript idioms when accessing them. For example, instead of accessing a java.util.Map using code such as:

var value1 = javaMap["key1"]
var value2 = javaMap.key2

You must call the underlying Java methods instead:

var value1 = javaMap.get("key1")
var value2 = javaMap.get("key2")

Please note that these techniques are solely intended for developers who wish to take advantage of the productivity benefits of a scripted language while still having access to the full power of native Java APIs. They should not be used for end user scripting scenarios (eg. end user developed custom actions uploaded to the repository, workflow scripts, etc.).

Tuesday, February 22, 2011

Config for datasource configuration alfresco



java:comp/env/jdbc/dataSource




Getting and using the config service

/**
* Retrieves the list of configured dialog container pages
*
* @param context FacesContext
* @return The container pages
*/
protected List getDialogContainers(FacesContext context)
{
if ((this.dialogContainers == null) || (Application.isDynamicConfig(FacesContext.getCurrentInstance())))
{
this.dialogContainers = new ArrayList(2);

ConfigService configSvc = Application.getConfigService(context);
Config globalConfig = configSvc.getGlobalConfig();

if (globalConfig != null)
{
this.dialogContainers.add(globalConfig.getConfigElement("dialog-container").getValue());
this.dialogContainers.add(globalConfig.getConfigElement("plain-dialog-container").getValue());
}
}

return this.dialogContainers;
}

Accessing the components of Alfresco as portlet config

This config is available in the file
C:\Alfresco3.3.3\tomcat\webapps\alfresco\WEB-INF\portlet.xml

The class is haveing portletRuntime implementation as well.

Integration between spring and jsf

The spring beans can be used in the JSF and the JSF beans in Spring this is possible because of the below configuration


"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">




org.alfresco.web.app.AlfrescoNavigationHandler
org.alfresco.web.app.AlfrescoVariableResolver

en








This file is available in the location
C:\Alfresco3.3.3\tomcat\webapps\alfresco\WEB-INF\faces-config-app.xml

Monday, February 14, 2011

Mail Issues

For any issues related to mail see MailActionExecuter,
it has ther code for sending mail to group as well as to user

protected void executeImpl(
final Action ruleAction,
final NodeRef actionedUponNodeRef)
{
// Create the mime mail message
MimeMessagePreparator mailPreparer = new MimeMessagePreparator()
{
@SuppressWarnings("unchecked")
public void prepare(MimeMessage mimeMessage) throws MessagingException
{
if (logger.isDebugEnabled())
{
logger.debug(ruleAction.getParameterValues());
}

MimeMessageHelper message = new MimeMessageHelper(mimeMessage);

// set header encoding if one has been supplied
if (headerEncoding != null && headerEncoding.length() != 0)
{
mimeMessage.setHeader("Content-Transfer-Encoding", headerEncoding);
}

// set recipient
String to = (String)ruleAction.getParameterValue(PARAM_TO);
if (to != null && to.length() != 0)
{
message.setTo(to);
}
else
{
// see if multiple recipients have been supplied - as a list of authorities
Serializable authoritiesValue = ruleAction.getParameterValue(PARAM_TO_MANY);
List authorities = null;
if (authoritiesValue != null)
{
if (authoritiesValue instanceof String)
{
authorities = new ArrayList(1);
authorities.add((String)authoritiesValue);
}
else
{
authorities = (List)authoritiesValue;
}
}

if (authorities != null && authorities.size() != 0)
{
List recipients = new ArrayList(authorities.size());
for (String authority : authorities)
{
AuthorityType authType = AuthorityType.getAuthorityType(authority);
if (authType.equals(AuthorityType.USER))
{
if (personService.personExists(authority) == true)
{
NodeRef person = personService.getPerson(authority);
String address = (String)nodeService.getProperty(person, ContentModel.PROP_EMAIL);
if (address != null && address.length() != 0 && validateAddress(address))
{
recipients.add(address);
}
}
}
else if (authType.equals(AuthorityType.GROUP))
{
// else notify all members of the group
Set users = authorityService.getContainedAuthorities(AuthorityType.USER, authority, false);
for (String userAuth : users)
{
if (personService.personExists(userAuth) == true)
{
NodeRef person = personService.getPerson(userAuth);
String address = (String)nodeService.getProperty(person, ContentModel.PROP_EMAIL);
if (address != null && address.length() != 0)
{
recipients.add(address);
}
}
}
}
}

message.setTo(recipients.toArray(new String[recipients.size()]));
}
else
{
// No recipiants have been specified
logger.error("No recipiant has been specified for the mail action");
}
}

// set subject line
message.setSubject((String)ruleAction.getParameterValue(PARAM_SUBJECT));

// See if an email template has been specified
String text = null;
NodeRef templateRef = (NodeRef)ruleAction.getParameterValue(PARAM_TEMPLATE);
if (templateRef != null)
{
// build the email template model
Map model = createEmailTemplateModel(actionedUponNodeRef);

// process the template against the model
text = templateService.processTemplate("freemarker", templateRef.toString(), model);
}

// set the text body of the message
if (text == null)
{
text = (String)ruleAction.getParameterValue(PARAM_TEXT);
}
message.setText(text);

// set the from address
NodeRef person = personService.getPerson(authService.getCurrentUserName());

String fromActualUser = null;
if (person != null)
{
fromActualUser = (String) nodeService.getProperty(person, ContentModel.PROP_EMAIL);
}
if( fromActualUser != null && fromActualUser.length() != 0)
{
message.setFrom(fromActualUser);
}
else
{
String from = (String)ruleAction.getParameterValue(PARAM_FROM);
if (from == null || from.length() == 0)
{
message.setFrom(fromAddress);
}
else
{
message.setFrom(from);
}
}
}
};

try
{
// Send the message unless we are in "testMode"
if(!testMode)
{
javaMailSender.send(mailPreparer);
}
else
{
try {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
mailPreparer.prepare(mimeMessage);
lastTestMessage = mimeMessage;
} catch(Exception e) {
System.err.println(e);
}
}
}
catch (MailException e)
{
String to = (String)ruleAction.getParameterValue(PARAM_TO);
if (to == null)
{
Object obj = ruleAction.getParameterValue(PARAM_TO_MANY);
if (obj != null)
{
to = obj.toString();
}
}

logger.error("Failed to send email to " + to, e);

throw new AlfrescoRuntimeException("Failed to send email to:" + to, e);
}
}

Friday, February 4, 2011

Refreshing the richlist

If I want to reset the data then use the binding parameter.
In the startworkflowwizard,you can see one component by name packageRichnamelist,which is getting nullified.
Since its been binded to the richlist,whenever you make the value of this
component null then that portion will get refreshed.

Ex:

JSP code :
binding="#{WizardManager.bean.packageItemsRichList}"
styleClass="recordSet" headerStyleClass="recordSetHeader" rowStyleClass="recordSetRow"
altRowStyleClass="recordSetRowAlt" width="100%" pageSize="10"
initialSortColumn="name" initialSortDescending="true">


Java code :

// reset the rich list so it re-renders
this.packageItemsRichList.setValue(null);


Refer to the class StartWorkflowWizard

Thursday, February 3, 2011

refer to the class for checking how the groups will be created in alfresco.





${ldap.synchronization.active}




${ldap.synchronization.queryBatchSize}




${ldap.synchronization.attributeBatchSize}




${ldap.synchronization.groupQuery}


Toolbars ---> Check Alfresco

IF it is not available then do the below step


Go to Help --> About MicrosoftWindows -->DisabledItemss --> Enable Alfresco