Amazon has opened SimpleDB service
Now you can easily outsource your database hosting. One more step to enabling infrastructures that are completely build using SaS approach.
Good analysis of the topic is here
Now you can easily outsource your database hosting. One more step to enabling infrastructures that are completely build using SaS approach.
Good analysis of the topic is here
Posted by Mykola Paliyenko at 4:00 PM 0 comments
Not Java but definitely Enterprise.
Like many other companies one day we faced the problem when bash was not enough for facilitating work of our product. We started investigation about what language to use to use in addition to simple bash scripts.
As you see Python is a winner due to the simplest syntax and good experience of using it in Google and Amazon.
Hope this helps to make scripting in our company more consistent.
Posted by Mykola Paliyenko at 1:37 PM 7 comments
I have configured some properties files for the application using the PropertyPlaceholderConfigurer. How can I access these properties in JSP?
package com.sonopia.sonoportal.web.util;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
/**
* Bean that should be used instead of the {@link PropertyPlaceholderConfigurer} if you want to have
* access to the resolved properties not obly from the Spring context. e.g. from JSP or so. More
* details about usage here http://wiki.sonopia.com/x/GmQ
*
* @author Mykola Palienko
*/
public class ExposablePropertyPaceholderConfigurer extends PropertyPlaceholderConfigurer {
private Map<String, String> resolvedProps;
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
Properties props) throws BeansException {
super.processProperties(beanFactoryToProcess, props);
resolvedProps = new HashMap<String, String>();
for (Object key : props.keySet()) {
String keyStr = key.toString();
resolvedProps.put(keyStr, parseStringValue(props.getProperty(keyStr), props,
new HashSet()));
}
}
public Map<String, String> getResolvedProps() {
return Collections.unmodifiableMap(resolvedProps);
}
}
<bean id="propertyConfigurer" class="com.sonopia.sonoportal.web.util.ExposablePropertyPaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:sonoportal.properties</value>
<value>classpath:sonoportal.custom.properties</value>
<value>classpath:sonoportal.buildInfo.properties</value>
</list>
</property>
</bean>
/**
* Copyright 2005-2006 Sonopia Corporation
*/
package com.sonopia.sonoportal.web.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.sonopia.sonoportal.web.util.ExposablePropertyPaceholderConfigurer;
/**
* Listener that exposes properties configured by {@link ExposablePropertyPaceholderConfigurer} to
* the web application context.
* More details about usage here http://wiki.sonopia.com/x/GmQ
*
* @author Mykola Palienko
*/
public class ConfigPropertiesExposerListener implements ServletContextListener {
public static final String DEFAULT_PROPERTIES_BEAN_NAME = "propertyConfigurer";
public static final String DEFAULT_CONTEXT_PROPERTY = "configProperties";
private String propertiesBeanName = DEFAULT_PROPERTIES_BEAN_NAME;
private String contextProperty = DEFAULT_CONTEXT_PROPERTY;
public void contextDestroyed(ServletContextEvent sce) {
}
public void contextInitialized(ServletContextEvent sce) {
// TODO add ability to configure non default values via serveltContexParams
ServletContext servletContext = sce.getServletContext();
WebApplicationContext context = WebApplicationContextUtils
.getRequiredWebApplicationContext(servletContext);
ExposablePropertyPaceholderConfigurer configurer =
(ExposablePropertyPaceholderConfigurer) context.getBean(propertiesBeanName);
sce.getServletContext().setAttribute(contextProperty, configurer.getResolvedProps());
}
}
<listener>
<listener-class>
com.sonopia.sonoportal.web.listener.ConfigPropertiesExposerListener
</listener-class>
</listener>
${configProperties['website.hostname']}
Posted by Mykola Paliyenko at 1:20 PM 3 comments
Labels: Configuration, java, JSP, Spring
Unlike a locale information that is passed by browsers via HTTP header, there is no straightforward way to retrieve the information about client timezone offset.
I also have not found any ready-to-use solutions to workaround this in web and one day when we've been posted the bug that our SMS sending times appears to be in the server timezone. I've found the solution.
The idea is pretty easy, the only way you can pass client timezone to the server is by calculating it using
var tzo = new Date().getTimezoneOffset();
<c:if test="${sessionScope['sonoportal.timezoneOffset'] == null}">
<!--Setting TZ offset-->
<script type="text/javascript">
var tzo = new Date().getTimezoneOffset();
document.cookie = "timezoneOffset=" + escape(tzo * (-1));
</script>
</c:if>
package com.sonopia.sonoportal.web.filter;
import java.io.IOException;
import java.util.TimeZone;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.jstl.core.Config;
import org.apache.commons.lang.time.DateUtils;
/**
* @author Mykola Paliyenko
*/
public class SetTimezoneOffsetFilter implements Filter {
public static final String PROPERTY_TIMEZONE_OFFEST = "sonoportal.timezoneOffset";
public static final String COOKIE_NAME = "timezoneOffset";
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (req.getSession().getAttribute(PROPERTY_TIMEZONE_OFFEST) == null) {
if (req.getCookies() != null) {
for (Cookie cookie : req.getCookies()) {
if (COOKIE_NAME.equals(cookie.getName())) {
int timezoneOffsetMinutes = Integer.parseInt(cookie.getValue());
TimeZone timeZone = TimeZone.getTimeZone("GMT");
timeZone.setRawOffset(
(int) (timezoneOffsetMinutes * DateUtils.MILLIS_PER_MINUTE));
Config.set(req.getSession(), Config.FMT_TIME_ZONE, timeZone);
req.getSession().setAttribute(
PROPERTY_TIMEZONE_OFFEST, timezoneOffsetMinutes);
// removing cookie, Sun sucks as usual in their API
cookie.setMaxAge(0);
res.addCookie(cookie);
}
}
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig config) throws ServletException {
}
}
<filter>
<filter-name>SetTimezoneOffsetFilter</filter-name>
<filter-class>
com.sonopia.sonoportal.web.filter.SetTimezoneOffsetFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>SetTimezoneOffsetFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Posted by Mykola Paliyenko at 1:25 PM 8 comments
This blog is about building feature rich application based on Java open source frameworks, problems and solution related to it. Creating our product day by day from prototype to the live system, from 4 developers to 30+, we get valuable experience that might be useful to share with community.
Posted by Mykola Paliyenko at 9:50 AM 0 comments