You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@roller.apache.org by Glen Mazza <gl...@gmail.com> on 2014/09/03 15:43:37 UTC

Re: svn commit: r1622172 - in /roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering: filters/ util/mobile/

Hi Greg, have to veto this change.  You have to do 4(b) and 4(d) of here 
to bring the code in: http://www.apache.org/licenses/LICENSE-2.0

4(b) just below the license header add something like "Code from Spring 
Mobile modified by use in Apache Roller"  This also helps Roller coders 
so we know where the code came from, where we need to research for more 
info, etc., that it is not our own.

4(d) add this blurb to our NOTICE file: 
https://github.com/spring-projects/spring-mobile/blob/master/NOTICE. 
Also, add the version.txt to the NOTICE file (it needs to be updated 
when we update the NOTICE file anyway) so we don't need version.txt anymore.

Regards,
Glen


On 09/03/2014 03:13 AM, ghuber@apache.org wrote:
> Author: ghuber
> Date: Wed Sep  3 07:13:17 2014
> New Revision: 1622172
>
> URL:http://svn.apache.org/r1622172
> Log:
> Alternate device type resolution for mobile themes
>
> Added:
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/filters/DeviceResolverRequestFilter.java
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/Device.java
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceResolver.java
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceType.java
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceUtils.java
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDevice.java
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDeviceResolver.java
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/MobileDeviceRepository.java
>      roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/version.txt
>
> Added: roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/filters/DeviceResolverRequestFilter.java
> URL:http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/filters/DeviceResolverRequestFilter.java?rev=1622172&view=auto
> ==============================================================================
> --- roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/filters/DeviceResolverRequestFilter.java (added)
> +++ roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/filters/DeviceResolverRequestFilter.java Wed Sep  3 07:13:17 2014
> @@ -0,0 +1,83 @@
> +/*
> + * Copyright 2010-2014 the original author or authors.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.roller.weblogger.ui.rendering.filters;
> +
> +import java.io.IOException;
> +
> +import javax.servlet.Filter;
> +import javax.servlet.FilterChain;
> +import javax.servlet.ServletException;
> +import javax.servlet.http.HttpServletRequest;
> +import javax.servlet.http.HttpServletResponse;
> +
> +import org.apache.roller.weblogger.ui.rendering.util.mobile.Device;
> +import org.apache.roller.weblogger.ui.rendering.util.mobile.DeviceResolver;
> +import org.apache.roller.weblogger.ui.rendering.util.mobile.DeviceUtils;
> +import org.apache.roller.weblogger.ui.rendering.util.mobile.LiteDeviceResolver;
> +import org.springframework.web.filter.OncePerRequestFilter;
> +
> +/**
> + * A Servlet 2.3 Filter that resolves the Device that originated the web
> + * request. The resolved Device is exported as a request attribute under the
> + * well-known name of {@link DeviceUtils#CURRENT_DEVICE_ATTRIBUTE}. Request
> + * handlers such as @Controllers and views may then access the currentDevice to
> + * vary their control and rendering logic, respectively.
> + *
> + * <!-- Spring-mobile based device type resolver --> <filter>
> + * <filter-name>DeviceResolverRequestFilter</filter-name>
> + * <filter-class>org.apache
> + * .roller.weblogger.ui.rendering.filters.DeviceResolverRequestFilter
> + * </filter-class> </filter>
> + *
> + * <!-- Mobile device detection (Once per request)--> <filter-mapping>
> + * <filter-name>DeviceResolverRequestFilter</filter-name>
> + * <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher>
> + * </filter-mapping>
> + *
> + * @author Roy Clarkson
> + */
> +public class DeviceResolverRequestFilter extends OncePerRequestFilter {
> +
> +    private final DeviceResolver deviceResolver;
> +
> +    /**
> +     * Create a device resolving {@link Filter} that defaults to a
> +     * {@link LiteDeviceResolver} implementation.
> +     */
> +    public DeviceResolverRequestFilter() {
> +        this(new LiteDeviceResolver());
> +    }
> +
> +    /**
> +     * Create a device resolving {@link Filter}.
> +     *
> +     * @param deviceResolver
> +     *            the device resolver to delegate to.
> +     */
> +    public DeviceResolverRequestFilter(DeviceResolver deviceResolver) {
> +        this.deviceResolver = deviceResolver;
> +    }
> +
> +    @Override
> +    protected void doFilterInternal(HttpServletRequest request,
> +            HttpServletResponse response, FilterChain filterChain)
> +            throws ServletException, IOException {
> +        Device device = deviceResolver.resolveDevice(request);
> +        request.setAttribute(DeviceUtils.CURRENT_DEVICE_ATTRIBUTE, device);
> +        filterChain.doFilter(request, response);
> +    }
> +
> +}
>
> Added: roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/Device.java
> URL:http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/Device.java?rev=1622172&view=auto
> ==============================================================================
> --- roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/Device.java (added)
> +++ roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/Device.java Wed Sep  3 07:13:17 2014
> @@ -0,0 +1,50 @@
> +/*
> + * Copyright 2010-2014 the original author or authors.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.roller.weblogger.ui.rendering.util.mobile;
> +
> +/**
> + * A model for the user agent or device that submitted the current request.
> + * Callers may introspect this model to vary UI control or rendering logic by
> + * device type.
> + *
> + * @author Keith Donald
> + * @author Roy Clarkson
> + * @author Scott Rossillo
> + */
> +public interface Device {
> +
> +	/**
> +	 * True if this device is not a mobile or tablet device.
> +	 */
> +	boolean isNormal();
> +
> +	/**
> +	 * True if this device is a mobile device such as an Apple iPhone or an
> +	 * Nexus One Android. Could be used by a pre-handle interceptor to redirect
> +	 * the user to a dedicated mobile web site. Could be used to apply a
> +	 * different page layout or stylesheet when the device is a mobile device.
> +	 */
> +	boolean isMobile();
> +
> +	/**
> +	 * True if this device is a tablet device such as an Apple iPad or a
> +	 * Motorola Xoom. Could be used by a pre-handle interceptor to redirect the
> +	 * user to a dedicated tablet web site. Could be used to apply a different
> +	 * page layout or stylesheet when the device is a tablet device.
> +	 */
> +	boolean isTablet();
> +
> +}
> \ No newline at end of file
>
> Added: roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceResolver.java
> URL:http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceResolver.java?rev=1622172&view=auto
> ==============================================================================
> --- roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceResolver.java (added)
> +++ roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceResolver.java Wed Sep  3 07:13:17 2014
> @@ -0,0 +1,33 @@
> +/*
> + * Copyright 2010-2014 the original author or authors.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.roller.weblogger.ui.rendering.util.mobile;
> +
> +import javax.servlet.http.HttpServletRequest;
> +
> +/**
> + * Service interface for resolving Devices that originate web requests with the
> + * application.
> + *
> + * @author Keith Donald
> + */
> +public interface DeviceResolver {
> +
> +	/**
> +	 * Resolve the device that originated the web request.
> +	 */
> +	Device resolveDevice(HttpServletRequest request);
> +
> +}
>
> Added: roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceType.java
> URL:http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceType.java?rev=1622172&view=auto
> ==============================================================================
> --- roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceType.java (added)
> +++ roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceType.java Wed Sep  3 07:13:17 2014
> @@ -0,0 +1,40 @@
> +/*
> + * Copyright 2010-2014 the original author or authors.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.roller.weblogger.ui.rendering.util.mobile;
> +
> +/**
> + * Enumeration for the type of device that has been resolved
> + *
> + * @author Roy Clarkson
> + */
> +public enum DeviceType {
> +
> +	/**
> +	 * Represents a normal device. i.e. a browser on a desktop or laptop
> +	 * computer. DO NOT USE FOR COMPARISON.
> +	 */
> +	NORMAL,
> +
> +	/**
> +	 * Represents a mobile device, such as an iPhone. DO NOT USE FOR COMPARISON.
> +	 */
> +	MOBILE,
> +
> +	/**
> +	 * Represents a tablet device, such as an iPad. DO NOT USE FOR COMPARISON.
> +	 */
> +	TABLET
> +}
>
> Added: roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceUtils.java
> URL:http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceUtils.java?rev=1622172&view=auto
> ==============================================================================
> --- roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceUtils.java (added)
> +++ roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/DeviceUtils.java Wed Sep  3 07:13:17 2014
> @@ -0,0 +1,83 @@
> +/*
> + * Copyright 2010-2014 the original author or authors.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.roller.weblogger.ui.rendering.util.mobile;
> +
> +import javax.servlet.http.HttpServletRequest;
> +
> +import org.springframework.web.context.request.RequestAttributes;
> +
> +/**
> + * Static helper for accessing request-scoped Device values.
> + *
> + * @author Keith Donald
> + */
> +public class DeviceUtils {
> +
> +	/**
> +	 * The name of the request attribute the current Device is indexed by. The
> +	 * attribute name is 'currentDevice'.
> +	 */
> +	public static final String CURRENT_DEVICE_ATTRIBUTE = "currentDevice";
> +
> +	/**
> +	 * Static utility method that extracts the current device from the web
> +	 * request. Encapsulates the {@link HttpServletRequest#getAttribute(String)}
> +	 * lookup.
> +	 *
> +	 * @param request
> +	 *            the servlet request
> +	 * @return the current device, or null if no device has been resolved for
> +	 *         the request
> +	 */
> +	public static Device getCurrentDevice(HttpServletRequest request) {
> +		return (Device) request.getAttribute(CURRENT_DEVICE_ATTRIBUTE);
> +	}
> +
> +	/**
> +	 * Static utility method that extracts the current device from the web
> +	 * request. Encapsulates the {@link HttpServletRequest#getAttribute(String)}
> +	 * lookup. Throws a runtime exception if the current device has not been
> +	 * resolved.
> +	 *
> +	 * @param request
> +	 *            the servlet request
> +	 * @return the current device
> +	 */
> +	public static Device getRequiredCurrentDevice(HttpServletRequest request) {
> +		Device device = getCurrentDevice(request);
> +		if (device == null) {
> +			throw new IllegalStateException(
> +					"No currenet device is set in this request and one is required - have you configured a DeviceResolvingHandlerInterceptor?");
> +		}
> +		return device;
> +	}
> +
> +	/**
> +	 * Static utility method that extracts the current device from the request
> +	 * attributes map. Encapsulates the
> +	 * {@link HttpServletRequest#getAttribute(String)} lookup.
> +	 *
> +	 * @param attributes
> +	 *            the request attributes
> +	 * @return the current device, or null if no device has been resolved for
> +	 *         the request
> +	 */
> +	public static Device getCurrentDevice(RequestAttributes attributes) {
> +		return (Device) attributes.getAttribute(CURRENT_DEVICE_ATTRIBUTE,
> +				RequestAttributes.SCOPE_REQUEST);
> +	}
> +
> +}
>
> Added: roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDevice.java
> URL:http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDevice.java?rev=1622172&view=auto
> ==============================================================================
> --- roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDevice.java (added)
> +++ roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDevice.java Wed Sep  3 07:13:17 2014
> @@ -0,0 +1,70 @@
> +/*
> + * Copyright 2010-2014 the original author or authors.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.roller.weblogger.ui.rendering.util.mobile;
> +
> +/**
> + * A lightweight Device implementation suitable for use as support code.
> + * Typically used to hold the output of a device resolution invocation.
> + *
> + * @author Keith Donald
> + * @author Roy Clarkson
> + * @author Scott Rossillo
> + */
> +class LiteDevice implements Device {
> +
> +	public static final LiteDevice NORMAL_INSTANCE = new LiteDevice(
> +			DeviceType.NORMAL);
> +
> +	public static final LiteDevice MOBILE_INSTANCE = new LiteDevice(
> +			DeviceType.MOBILE);
> +
> +	public static final LiteDevice TABLET_INSTANCE = new LiteDevice(
> +			DeviceType.TABLET);
> +
> +	public boolean isNormal() {
> +		return this.deviceType == DeviceType.NORMAL;
> +	}
> +
> +	public boolean isMobile() {
> +		return this.deviceType == DeviceType.MOBILE;
> +	}
> +
> +	public boolean isTablet() {
> +		return this.deviceType == DeviceType.TABLET;
> +	}
> +
> +	public DeviceType getDeviceType() {
> +		return this.deviceType;
> +	}
> +
> +	public String toString() {
> +		StringBuilder builder = new StringBuilder();
> +		builder.append("[LiteDevice ");
> +		builder.append("type").append("=").append(this.deviceType);
> +		builder.append("]");
> +		return builder.toString();
> +	}
> +
> +	private final DeviceType deviceType;
> +
> +	/**
> +	 * Creates a LiteDevice.
> +	 */
> +	private LiteDevice(DeviceType deviceType) {
> +		this.deviceType = deviceType;
> +	}
> +
> +}
> \ No newline at end of file
>
> Added: roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDeviceResolver.java
> URL:http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDeviceResolver.java?rev=1622172&view=auto
> ==============================================================================
> --- roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDeviceResolver.java (added)
> +++ roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/LiteDeviceResolver.java Wed Sep  3 07:13:17 2014
> @@ -0,0 +1,205 @@
> +/*
> + * Copyright 2010-2014 the original author or authors.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.roller.weblogger.ui.rendering.util.mobile;
> +
> +import java.util.ArrayList;
> +import java.util.Arrays;
> +import java.util.Enumeration;
> +import java.util.List;
> +import javax.servlet.http.HttpServletRequest;
> +
> +/**
> + * A "lightweight" device resolver algorithm based on Wordpress's Mobile pack.
> + * Detects the presence of a mobile device and works for a large percentage of
> + * mobile browsers. Does not perform any device capability mapping, if you need
> + * that consider WURFL.
> + *
> + * The code is based primarily on a list of approximately 90 well-known mobile
> + * browser UA string snippets, with a couple of special cases for Opera Mini,
> + * the W3C default delivery context and certain other Windows browsers. The code
> + * also looks to see if the browser advertises WAP capabilities as a hint.
> + *
> + * Tablet resolution is also performed based on known tablet browser UA strings.
> + * Android tablets are detected based on <a href=
> + *"http://googlewebmastercentral.blogspot.com/2011/03/mo-better-to-also-detect-mobile-user.html"
> + * >Google's recommendations</a>.
> + *
> + * @author Keith Donald
> + * @author Roy Clarkson
> + * @author Scott Rossillo
> + * @author Yuri Mednikov
> + */
> +public class LiteDeviceResolver implements DeviceResolver {
> +	private final List<String> mobileUserAgentPrefixes = new ArrayList<String>();
> +	private final List<String> mobileUserAgentKeywords = new ArrayList<String>();
> +	private final List<String> tabletUserAgentKeywords = new ArrayList<String>();
> +	private final List<String> normalUserAgentKeywords = new ArrayList<String>();
> +
> +	public LiteDeviceResolver() {
> +		init();
> +	}
> +
> +	public LiteDeviceResolver(List<String> normalUserAgentKeywords) {
> +		init();
> +		this.normalUserAgentKeywords.addAll(normalUserAgentKeywords);
> +	}
> +
> +	public Device resolveDevice(HttpServletRequest request) {
> +		String userAgent = request.getHeader("User-Agent");
> +		// UserAgent keyword detection of Normal devices
> +		if (userAgent != null) {
> +			userAgent = userAgent.toLowerCase();
> +			for (String keyword : normalUserAgentKeywords) {
> +				if (userAgent.contains(keyword)) {
> +					return resolveFallback(request);
> +				}
> +			}
> +		}
> +		// UserAgent keyword detection of Tablet devices
> +		if (userAgent != null) {
> +			userAgent = userAgent.toLowerCase();
> +			// Android special case
> +			if (userAgent.contains("android") && !userAgent.contains("mobile")) {
> +				return LiteDevice.TABLET_INSTANCE;
> +			}
> +			// Kindle Fire special case
> +			if (userAgent.contains("silk") && !userAgent.contains("mobile")) {
> +				return LiteDevice.TABLET_INSTANCE;
> +			}
> +			for (String keyword : tabletUserAgentKeywords) {
> +				if (userAgent.contains(keyword)) {
> +					return LiteDevice.TABLET_INSTANCE;
> +				}
> +			}
> +		}
> +		// UAProf detection
> +		if (request.getHeader("x-wap-profile") != null
> +				|| request.getHeader("Profile") != null) {
> +			return LiteDevice.MOBILE_INSTANCE;
> +		}
> +		// User-Agent prefix detection
> +		if (userAgent != null && userAgent.length() >= 4) {
> +			String prefix = userAgent.substring(0, 4).toLowerCase();
> +			if (mobileUserAgentPrefixes.contains(prefix)) {
> +				return LiteDevice.MOBILE_INSTANCE;
> +			}
> +		}
> +		// Accept-header based detection
> +		String accept = request.getHeader("Accept");
> +		if (accept != null && accept.contains("wap")) {
> +			return LiteDevice.MOBILE_INSTANCE;
> +		}
> +		// UserAgent keyword detection for Mobile devices
> +		if (userAgent != null) {
> +			for (String keyword : mobileUserAgentKeywords) {
> +				if (userAgent.contains(keyword)) {
> +					return LiteDevice.MOBILE_INSTANCE;
> +				}
> +			}
> +		}
> +		// OperaMini special case
> +		@SuppressWarnings("rawtypes")
> +		Enumeration headers = request.getHeaderNames();
> +		while (headers.hasMoreElements()) {
> +			String header = (String) headers.nextElement();
> +			if (header.contains("OperaMini")) {
> +				return LiteDevice.MOBILE_INSTANCE;
> +			}
> +		}
> +		return resolveFallback(request);
> +	}
> +
> +	// subclassing hooks
> +	/**
> +	 * List of user agent prefixes that identify mobile devices. Used primarily
> +	 * to match by operator or handset manufacturer.
> +	 */
> +	protected List<String> getMobileUserAgentPrefixes() {
> +		return mobileUserAgentPrefixes;
> +	}
> +
> +	/**
> +	 * List of user agent keywords that identify mobile devices. Used primarily
> +	 * to match by mobile platform or operating system.
> +	 */
> +	protected List<String> getMobileUserAgentKeywords() {
> +		return mobileUserAgentKeywords;
> +	}
> +
> +	/**
> +	 * List of user agent keywords that identify tablet devices. Used primarily
> +	 * to match by tablet platform or operating system.
> +	 */
> +	protected List<String> getTabletUserAgentKeywords() {
> +		return tabletUserAgentKeywords;
> +	}
> +
> +	/**
> +	 * List of user agent keywords that identify normal devices. Any items in
> +	 * this list take precedence over the mobile and tablet user agent keywords,
> +	 * effectively overriding those.
> +	 */
> +	protected List<String> getNormalUserAgentKeywords() {
> +		return normalUserAgentKeywords;
> +	}
> +
> +	/**
> +	 * Initialize this device resolver implementation. Registers the known set
> +	 * of device signature strings. Subclasses may override to register
> +	 * additional strings.
> +	 */
> +	protected void init() {
> +		getMobileUserAgentPrefixes().addAll(
> +				Arrays.asList(KNOWN_MOBILE_USER_AGENT_PREFIXES));
> +		getMobileUserAgentKeywords().addAll(
> +				Arrays.asList(KNOWN_MOBILE_USER_AGENT_KEYWORDS));
> +		getTabletUserAgentKeywords().addAll(
> +				Arrays.asList(KNOWN_TABLET_USER_AGENT_KEYWORDS));
> +	}
> +
> +	/**
> +	 * Fallback called if no mobile device is matched by this resolver. The
> +	 * default implementation of this method returns a "normal" {@link Device}
> +	 * that is neither mobile or a tablet. Subclasses may override to try
> +	 * additional mobile or tablet device matching before falling back to a
> +	 * "normal" device.
> +	 */
> +	protected Device resolveFallback(HttpServletRequest request) {
> +		return LiteDevice.NORMAL_INSTANCE;
> +	}
> +
> +	// internal helpers
> +	private static final String[] KNOWN_MOBILE_USER_AGENT_PREFIXES = new String[] {
> +			"w3c ", "w3c-", "acs-", "alav", "alca", "amoi", "audi", "avan",
> +			"benq", "bird", "blac", "blaz", "brew", "cell", "cldc", "cmd-",
> +			"dang", "doco", "eric", "hipt", "htc_", "inno", "ipaq", "ipod",
> +			"jigs", "kddi", "keji", "leno", "lg-c", "lg-d", "lg-g", "lge-",
> +			"lg/u", "maui", "maxo", "midp", "mits", "mmef", "mobi", "mot-",
> +			"moto", "mwbp", "nec-", "newt", "noki", "palm", "pana", "pant",
> +			"phil", "play", "port", "prox", "qwap", "sage", "sams", "sany",
> +			"sch-", "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem",
> +			"smal", "smar", "sony", "sph-", "symb", "t-mo", "teli", "tim-",
> +			"tosh", "tsm-", "upg1", "upsi", "vk-v", "voda", "wap-", "wapa",
> +			"wapi", "wapp", "wapr", "webc", "winw", "winw", "xda ", "xda-" };
> +	private static final String[] KNOWN_MOBILE_USER_AGENT_KEYWORDS = new String[] {
> +			"blackberry", "webos", "ipod", "lge vx", "midp", "maemo", "mmp",
> +			"mobile", "netfront", "hiptop", "nintendo DS", "novarra",
> +			"openweb", "opera mobi", "opera mini", "palm", "psp", "phone",
> +			"smartphone", "symbian", "up.browser", "up.link", "wap",
> +			"windows ce" };
> +	private static final String[] KNOWN_TABLET_USER_AGENT_KEYWORDS = new String[] {
> +			"ipad", "playbook", "hp-tablet", "kindle" };
> +}
> \ No newline at end of file
>
> Added: roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/MobileDeviceRepository.java
> URL:http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/MobileDeviceRepository.java?rev=1622172&view=auto
> ==============================================================================
> --- roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/MobileDeviceRepository.java (added)
> +++ roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/MobileDeviceRepository.java Wed Sep  3 07:13:17 2014
> @@ -0,0 +1,87 @@
> +/*
> + * Copyright 2010-2014 the original author or authors.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.roller.weblogger.ui.rendering.util.mobile;
> +
> +import javax.servlet.http.HttpServletRequest;
> +
> +/**
> + * The Class MobileDeviceRepository.
> + */
> +public class MobileDeviceRepository {
> +
> +	/**
> +	 * The Enum DeviceType.
> +	 *
> +	 * eg use deviceType.equals(DeviceType.mobile) for camparison.
> +	 */
> +	public enum DeviceType {
> +		standard, mobile
> +	}
> +
> +	/**
> +	 * Check if device in request is a mobile device.
> +	 *
> +	 * @param request
> +	 *            the request
> +	 *
> +	 * @return boolean
> +	 */
> +	public static boolean isMobileDevice(HttpServletRequest request) {
> +
> +		// String userAgent = request.getHeader("User-Agent");
> +		// System.out.println(userAgent);
> +
> +		Device device = DeviceUtils.getCurrentDevice(request);
> +
> +		if (device == null) {
> +			// log.info("no device detected");
> +			return false;
> +		} else if (device.isNormal()) {
> +			// log.info("Device is normal");
> +			return false;
> +		} else if (device.isMobile()) {
> +			// log.info("Device is mobile");
> +			// System.out.println(userAgent);
> +			return true;
> +		} else if (device.isTablet()) {
> +			// log.info("Device is tablet");
> +			// System.out.println(userAgent);
> +			return true;
> +		} else {
> +			return false;
> +		}
> +
> +	}
> +
> +	/**
> +	 * Gets the request device type.
> +	 *
> +	 * @param request
> +	 *            the request
> +	 *
> +	 * @return the request type
> +	 */
> +	public static DeviceType getRequestType(HttpServletRequest request) {
> +
> +		DeviceType type = DeviceType.standard;
> +
> +		if (isMobileDevice(request)) {
> +			type = DeviceType.mobile;
> +		}
> +		return type;
> +	}
> +
> +}
>
> Added: roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/version.txt
> URL:http://svn.apache.org/viewvc/roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/version.txt?rev=1622172&view=auto
> ==============================================================================
> --- roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/version.txt (added)
> +++ roller/trunk/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/mobile/version.txt Wed Sep  3 07:13:17 2014
> @@ -0,0 +1,6 @@
> +
> +Version Notes
> +
> +https://github.com/spring-projects/spring-mobile
> +
> +master >  LiteDeviceResolver 11 Feb 2014
>
>