Wednesday, June 1, 2011

Fitting website on Apple IPad

Hi,

Recently, we had to release an IPad version of one of our websites, an existing website needed to be converted to display on an IPad. I had a major issue when some one rendered the site from landscape to portrait and from portrait to landscape on an ipad, the site does not get auto fitted.

To overcome this issue, i had to set view port in meta tag on all my jsp pages.

I did something like this ::


<meta name="viewport" content="width=800" />


Now it renders site correctly on an ipad.. :)

Cheers,

Ujjwal Soni



Autofit textarea with dynamic text on load


Hi,

I wanted to autofit textarea rows which contained dynamic text from database on page load. I tried many plugins and other javascript tweaks. Atlast, i found a jquery plugin for this.

I did this as under::

Step 1 :: Add autogrow text area js file




<script src="<%=request.getContextPath()%>/script/jquery.autogrowtextarea.js">
</script>


Step 2 :: Call Text Area Exploder Function on page load


    $(document).ready(function() {
        $(&quot;#textAreaDescription&quot;).TextAreaExpander(); 
    
    }); 

You can download the js file from below link ::

https://sites.google.com/site/ujjwalbsoni/Home/jquery.autogrowtextarea.js

If you have any further queries, please let me know..

Cheers,

Ujjwal Soni




Thursday, May 26, 2011

The dynamic stylesheet language

Hi,

Recently i was searching for compacting heavy css for my website in less css with dynamic css code, i came across lesscss.org, it's a fabulous website which provides dynamic integration of css.

"LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions. LESS runs on both the client-side (IE 6+, Webkit, Firefox) and server-side, with Node.js."

http://lesscss.org/

Cheers,

Ujjwal Soni

Wednesday, May 11, 2011

Redirect all 404's to index page in php

This given PHP example redirect to index page if there is 404 error in your site.



Create the file app/app_error.php with the following code.

Code Example:


class AppError extends ErrorHandler {
    function error404($params) {
        // redirect to homepage
        $this->controller->redirect('/');
    }
}

 


Friday, April 29, 2011

Oracle SSO configuration with Alfresco

Hi,

I finally configured Oracle SSO with Alfresco. Below is how i achieved that.

I need to run Alfresco on tomcat deployed on other virtual terminal, i created a class file as under

-> STEP 1

package my.custom;

import java.io.IOException; 
import java.util.List;
import java.util.Locale;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.transaction.UserTransaction;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.AbstractAuthenticationFilter;
import org.alfresco.web.app.servlet.AuthenticationHelper;
import org.alfresco.web.bean.LoginBean;
import org.alfresco.web.bean.repository.User;
import org.alfresco.web.config.LanguagesConfigElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.config.ConfigService;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.alfresco.web.bean.repository.Repository;



public class OSSOAuthenticationFilter extends AbstractAuthenticationFilter implements Filter {
private static final String LOCALE = "locale";
public static final String MESSAGE_BUNDLE = "alfresco.messages.webclient";
private static Log logger = LogFactory.getLog(OSSOAuthenticationFilter.class);
private ServletContext context;
private String loginPage;
private AuthenticationComponent authComponent;
private AuthenticationService authService;
private TransactionService transactionService;
private PersonService personService;
private NodeService nodeService;
private List m_languages;

public OSSOAuthenticationFilter() {
super();
}

public void destroy() {
// Nothing to do
}

/**
* Run the filter
*
* @param sreq
* ServletRequest
* @param sresp
* ServletResponse
* @param chain
* FilterChain
* @exception IOException
* @exception ServletException
*/
public void doFilter(ServletRequest sreq, ServletResponse sresp, FilterChain chain) throws IOException, ServletException {
// Get the HTTP request/response/session
HttpServletRequest req = (HttpServletRequest) sreq;
HttpServletResponse resp = (HttpServletResponse) sresp;
HttpSession httpSess = req.getSession(true);

String userName = null;
//Get headers setted by the oracle sigle sign one server
java.util.Enumeration reqMap = req.getHeaders("Osso-User-Dn");

if (reqMap == null) {
logger.error("No user logged in");
} else {
while (reqMap.hasMoreElements()){
//Get from the full dn the username
userName = ((String)reqMap.nextElement()).split(",")[0].trim().toString().split("=")[1].trim().toString();
//String tmp = value.split(",")[0].trim().toString();
//userName = tmp.split("=")[1].trim().toString();
}
}

if (logger.isDebugEnabled()) {
logger.debug("OSSO : User = " + userName);
}

// See if there is a user in the session and test if it matches
User user = (User) httpSess.getAttribute(AuthenticationHelper.AUTHENTICATION_USER);

if (user != null) {
try {
// Debug
if (logger.isDebugEnabled())
logger.debug("OSSO : User " + user.getUserName() + " validate ticket");

if (user.getUserName().equals(userName)) {
UserTransaction tx1 = transactionService.getUserTransaction();
try {
tx1.begin();
authComponent.setCurrentUser(user.getUserName());
tx1.commit();
}catch(Exception ex){
logger.error("Failed due to transaction " + ex);
try {
tx1.rollback();
} catch (Exception ex2) {
logger.error("Failed to rollback transaction", ex2);
}

}
I18NUtil.setLocale(Application.getLanguage(httpSess));
chain.doFilter(sreq, sresp);
return;
} else {
// No match
//setAuthenticatedUser(req, httpSess, userName);
//below url is th oracle portal url
resp.sendRedirect("http://hostname:7778/alfresco");
return;
}
} catch (AuthenticationException ex) {
if (logger.isErrorEnabled())
logger.error("Failed to validate user " + user.getUserName(), ex);
}
}

setAuthenticatedUser(req, httpSess, userName);

// Redirect the login page as it is never seen as we always login by name
if (req.getRequestURI().endsWith(getLoginPage()) == true)
{
if (logger.isDebugEnabled())
logger.debug("Login page requested, chaining ...");

resp.sendRedirect(req.getContextPath() + "/faces/jsp/browse/browse.jsp");
return;
}
else
{
//below url is th oracle portal url
resp.sendRedirect("http://hostname:7778/alfresco");
//chain.doFilter(sreq, sresp);
return;
}

}

/**
* Set the authenticated user.
*
* It does not check that the user exists at the moment.
*
* @param req
* @param httpSess
* @param userName
*/
private void setAuthenticatedUser(HttpServletRequest req, HttpSession httpSess, String userName) {
if (userName != null){
UserTransaction tx1 = transactionService.getUserTransaction();
// Set the authentication
try {
tx1.begin();
authComponent.setCurrentUser(userName);
tx1.commit();
} catch (Throwable ex) {
logger.error(ex);
try {
tx1.rollback();
} catch (Exception ex2) {
logger.error("Failed to rollback transaction", ex2);
}
}

// Set up the user information
UserTransaction tx = transactionService.getUserTransaction();
NodeRef homeSpaceRef = null;
User user;
try {
tx.begin();
user = new User(userName, authService.getCurrentTicket(), personService.getPerson(userName));
homeSpaceRef = (NodeRef) nodeService.getProperty(personService.getPerson(userName), ContentModel.PROP_HOMEFOLDER);
if(homeSpaceRef == null) {
logger.warn("Home Folder is null for user '"+userName+"', using company_home.");
homeSpaceRef = (NodeRef) nodeService.getRootNode(Repository.getStoreRef());
}
user.setHomeSpaceId(homeSpaceRef.getId());
tx.commit();
} catch (Throwable ex) {
logger.error(ex);

try {
tx.rollback();
} catch (Exception ex2) {
logger.error("Failed to rollback transaction", ex2);
}

if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
} else {
throw new RuntimeException("Failed to set authenticated user", ex);
}
}

// Store the user
httpSess.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user);
httpSess.setAttribute(LoginBean.LOGIN_EXTERNAL_AUTH, Boolean.TRUE);

// Set the current locale from the Accept-Lanaguage header if available
Locale userLocale = parseAcceptLanguageHeader(req, m_languages);

if (userLocale != null) {
httpSess.setAttribute(LOCALE, userLocale);
httpSess.removeAttribute(MESSAGE_BUNDLE);
}

// Set the locale using the session
I18NUtil.setLocale(Application.getLanguage(httpSess));
}
}

public void init(FilterConfig config) throws ServletException {
this.context = config.getServletContext();
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
transactionService = serviceRegistry.getTransactionService();
nodeService = serviceRegistry.getNodeService();

authComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
authService = (AuthenticationService) ctx.getBean("authenticationService");
personService = (PersonService) ctx.getBean("personService");

// Get a list of the available locales
ConfigService configServiceService = (ConfigService) ctx.getBean("webClientConfigService");
LanguagesConfigElement configElement = (LanguagesConfigElement) configServiceService.getConfig("Languages").getConfigElement(LanguagesConfigElement.CONFIG_ELEMENT_ID);

m_languages = configElement.getLanguages();
}

/**
* Return the login page address
*
* @return String
*/
private String getLoginPage() {
if (loginPage == null) {
loginPage = Application.getLoginPage(context);
}

return loginPage;
}
}



-> STEP 2 Place this class file under
C:\Alfresco\tomcat\webapps\alfresco\WEB-INF\classes\my\custom

-> STEP 3 Now you need to configure proxy pass in oc4j's httpd.conf file


$ORACLE_HOME/Apache/Apache/conf/httpd.conf, add the following entries:                                                                                    ProxyPass /alfresco/ http://host:8080/alfresco/

ProxyPass /alfresco http://host:8080/alfresco/


ProxyPassReverse /alfresco/ http://host:8080/alfresco/

ProxyPassReverse /alfresco http://host:8080/alfresco/


-> STEP 4 Now you need to enable sso on oracle portal

edit $ORACLE_HOME/Apache/Apache/conf/mod_osso.conf, add the following lines just before the :

require valid-user
AuthType Basic


require valid-user
AuthType Basic


Please restart apache after you have made this configuration

-> STEP 5 If alfresco is already running then stop and start alfresco service from start menu under start -> alfresco -> stop alfreco virtual server

Thats it, now oracle sso is configured successfully for Alfreco

Try opening http://oc4jserverhost/alfresco, it will redirect to oracle portal sso login page, enter credentials, it will then redirect you to alfresco home page on successful login.

LOGOUT Link

Coming towards logout functionality, i need to make some changes to use oracle portal logout instead of alfresco built in logout.

You need to edit file C:\Alfresco\tomcat\webapps\alfresco\jsp\parts\titlebar.jsp


search for
a:actionLink


now replace that line with
a:actionLink id="logout" image="/images/icons/logout.gif" value="#{msg.logout} (#{NavigationBean.currentUser.userName})" rendered="#{!NavigationBean.isGuest}" href="http://hostname/pls/orasso/orasso.wwsso_app_admin.ls_logout?p_done_url=http%3A%2F%2Fhostname%2Falfresco" immediate="true"


Thats it, now logout functionality is integrated with oracle sso.

Any issues implementing this, feel free to contact me..

Cheers,

Ujjwal Soni

Tuesday, April 26, 2011

A nice book on smaller, faster, better way to build software

Last week, my friend sent me a link which contains great amount of information for building, testing and all other phases for software development.

Check out this link :: http://gettingreal.37signals.com/toc.php

Cheers,

Ujjwal Soni

Tuesday, March 15, 2011

Jquery Autocomplete with DataSource

Hi All,

Recently i needed an autocomplete textbox in which i need to store an ID and display a list. So, i gone for Jquery autocomplete which i was very used to. I have used this before but it was just for single list where i was not storing any ID. I tried my hands on with JSON using Jquery autocomplete but it was not giving me results the way i wanted.

So, finally, i found a solution as mentioned below ::

1) A textbox for autocomplete


<input type="text" id="input" name="input"/>


2) An onload script


function loadData(){
$("#input").autocomplete('<%=request.getContextPath()%>/showMyCity.do' , {
        extraParams: { locationName : function() { 
        return document.getElementById('input').value; 
            }
         },
        minChars: 0,
        width: 185,
        matchContains: "word",
        autoFill: false,
        max:50,
        formatItem:function(row) {
            return row[0];
        },
        formatResult: function(row) {
            return row[0];
        }
    });
    
    
    $("#input").result(function(event, data, formatted) {
        if (data)
            document.getElementById("selectedLocation").value=data[1];
            
            
    });

}



3) Jsp page which results your search :


<c:forEach items="${LOCATION_LIST}" var="bean">

<c:out value="${bean.description}"/>|<c:out value="${bean.code}"/>
</c:forEach>




With a pipe character added in between, you can hide/show text on autocomplete.

This resoved my issue and i need not  have to use JSON for that.

Cheers,

Ujjwal Soni

UBS