<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>philihp.com &#187; Java</title>
	<atom:link href="http://www.philihp.com/blog/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.philihp.com/blog</link>
	<description>I do things, and then I tell the internet about them.</description>
	<lastBuildDate>Mon, 06 Feb 2012 05:40:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Chained Struts Actions Accessible Only by Forward</title>
		<link>http://www.philihp.com/blog/2012/chained-struts-actions-that-accessible-only-by-forward/</link>
		<comments>http://www.philihp.com/blog/2012/chained-struts-actions-that-accessible-only-by-forward/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 05:40:05 +0000</pubDate>
		<dc:creator>philihp</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Action]]></category>
		<category><![CDATA[Forward]]></category>
		<category><![CDATA[Fragment]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Struts]]></category>
		<category><![CDATA[Struts 1.3]]></category>

		<guid isPermaLink="false">http://www.philihp.com/blog/?p=961</guid>
		<description><![CDATA[So I just stumbled into doing this little trick. It may go against some pattern, or best practice, but I&#8217;m sure there&#8217;s a use for it somewhere. In Struts 1.3 (and probably any Struts 1.x), it is sometimes useful to have a request chain across multiple Action classes, maybe to break them up into more [...]]]></description>
			<content:encoded><![CDATA[<p>So I just stumbled into doing this little trick. It may go against some pattern, or best practice, but I&#8217;m sure there&#8217;s a use for it somewhere.</p>
<p>In <a href="http://struts.apache.org/1.3.10/">Struts 1.3</a> (and probably any Struts 1.x), it is sometimes useful to have a request chain across multiple Action classes, maybe to break them up into more manageable sections. But maybe you don&#8217;t want step-2 of a multi-Action process be accessible externally. If you configure your Actions like this in your <code>struts-config.xml</code>, you can do just that.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;action</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;/refresh&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;com.philihp.action.RefreshPartOne&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;forward</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;default&quot;</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;/refresh#2.do&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/action<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;action</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;/refresh#2&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;com.philihp.action.RefreshPartTwo&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;forward</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;default&quot;</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;/&quot;</span> <span style="color: #000066;">redirect</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/action<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>To trigger it, have the user goto <code>/refresh.do</code>. Struts will call RefreshPartOne.execute(), and assuming it returns the default ActionForward, it will call RefreshPartTwo.execute().</p>
<p>If the user tries to call <code>/refresh#2.do</code>, they will get an error. The browser will strip out the <a href="http://en.wikipedia.org/wiki/Fragment_identifier">fragment identifier</a> from the URL and tell the server it wants to see /refresh, which doesn&#8217;t exist. It may be possible to carefully craft a request to the server though, and it&#8217;s up to your container (e.g. Tomcat, Glassfish) to strip out the fragment. Behavior is probably undefined because <a href="http://www.ietf.org/rfc/rfc1738.txt">RFC 1738</a> says the &#8216;<code>#</code>&#8216; is unsafe and should never be sent in a URL. So test it out if you&#8217;re really curious.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.philihp.com/blog/2012/chained-struts-actions-that-accessible-only-by-forward/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New in Java 7: switch()ing on Strings</title>
		<link>http://www.philihp.com/blog/2012/new-in-java-7-switching-on-strings/</link>
		<comments>http://www.philihp.com/blog/2012/new-in-java-7-switching-on-strings/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 04:49:57 +0000</pubDate>
		<dc:creator>philihp</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[java 7]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[switch]]></category>

		<guid isPermaLink="false">http://www.philihp.com/blog/?p=946</guid>
		<description><![CDATA[Finally, Java can switch on Strings! No more inefficient strings of if/else chains or Hash lookups or translation into Enums. Finally just clean readable and intuitive code. switch&#40;suit&#41; &#123; case &#34;club&#34;: case &#34;diamond&#34;: trickValue = 20; break; case &#34;heart&#34;: case &#34;spade&#34;: trickValue = 30; break; case &#34;no-trump&#34;: trickValue = 40; break; &#125; It&#8217;s actually just [...]]]></description>
			<content:encoded><![CDATA[<p>Finally, <a href="http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html">Java can switch on Strings</a>! No more inefficient strings of if/else chains or Hash lookups or translation into Enums. Finally just clean readable and intuitive code.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span>suit<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #0000ff;">&quot;club&quot;</span><span style="color: #339933;">:</span>
  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #0000ff;">&quot;diamond&quot;</span><span style="color: #339933;">:</span>
    trickValue <span style="color: #339933;">=</span> <span style="color: #cc66cc;">20</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #0000ff;">&quot;heart&quot;</span><span style="color: #339933;">:</span>
  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #0000ff;">&quot;spade&quot;</span><span style="color: #339933;">:</span>
    trickValue <span style="color: #339933;">=</span> <span style="color: #cc66cc;">30</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #0000ff;">&quot;no-trump&quot;</span><span style="color: #339933;">:</span>
    trickValue <span style="color: #339933;">=</span> <span style="color: #cc66cc;">40</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>It&#8217;s actually just syntactic sugar. The <a href="http://blogs.oracle.com/darcy/entry/project_coin_strings_in_switch">java compiler renders this all down to int switching</a> by pre-computing the <code>.hashcode()</code> of all of the labels since they have to be constants anyway (unlike languages like PHP where you can do <a href="http://programmersnotes.info/2009/03/06/trick-with-php-switch/">some really neat shenanigans</a>). Because this still renders down to primitives, Java still gets the <a href="http://en.wikipedia.org/wiki/Jump_table">jump table optimizations</a> that were the whole motivation of the switch construct in the first place.</p>
<p>If you use Eclipse, switching on a String will still probably give you an error. <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288548#c9">It wasn&#8217;t until September 2011&#8242;s release (3.7.1)</a> that this was implemented. There were versions of Indigo that didn&#8217;t support this, so you&#8217;ll need the latest one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.philihp.com/blog/2012/new-in-java-7-switching-on-strings/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adding Tiles to a Struts 1.3 Project with a Custom Request Processor</title>
		<link>http://www.philihp.com/blog/2011/adding-tiles-to-a-struts-1-3-project-with-a-custom-request-processor/</link>
		<comments>http://www.philihp.com/blog/2011/adding-tiles-to-a-struts-1-3-project-with-a-custom-request-processor/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 08:18:58 +0000</pubDate>
		<dc:creator>philihp</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Custom]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Override]]></category>
		<category><![CDATA[RequestProcessor]]></category>
		<category><![CDATA[Struts]]></category>
		<category><![CDATA[Struts 1.3]]></category>
		<category><![CDATA[Tiles]]></category>

		<guid isPermaLink="false">http://www.philihp.com/blog/?p=695</guid>
		<description><![CDATA[In Struts, if you wanted to do funny shenanigans (e.g. override the Roles checking for authorization, or override the ActionForm population to parse a JSON object rather than standard parameters) with the Struts Controller, up until Struts 1.2, you had to extend the Request Processor and configure the Struts ActionServlet to use it instead. This [...]]]></description>
			<content:encoded><![CDATA[<p>In Struts, if you wanted to do funny shenanigans (e.g. override the Roles checking for authorization, or override the ActionForm population to parse a JSON object rather than standard parameters) with the Struts Controller, up until Struts 1.2, you had to extend the Request Processor and configure the Struts ActionServlet to use it instead. This would get rather complicated when you tried to layer multiple custom controllers together, such as with the Validator and the Tiles plugins.</p>
<p>Struts 1.3 changed this behavior. Rather than all of the heavy lifting being offloaded onto the RequestProcessor object by the ActionServlet, instead there&#8217;s a <a href="http://struts.apache.org/1.x/userGuide/building_controller.html#request_processor">chain of commands</a> executed by a class called &#8220;<a href="http://svn.apache.org/repos/asf/struts/struts1/trunk/core/src/main/java/org/apache/struts/chain/ComposableRequestProcessor.java">ComposableRequestProcessor</a>, and it&#8217;s configured by <a href="http://svn.apache.org/repos/asf/struts/struts1/trunk/core/src/main/resources/org/apache/struts/chain/chain-config.xml">chain-config.xml</a>; which is in the struts-core JAR file. If you want to extend the controller to do out-of-the-ordinary stuff, you&#8217;re supposed to copy this file to somewhere else (like /WEB-inF/custom-chain-config.xml) edit it, and configure the ActionServlet to look at it instead like this</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>action<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.apache.struts.action.ActionServlet<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;init-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>config<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/WEB-INF/struts-config.xml<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/init-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;init-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>chainConfig<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/WEB-INF/custom-chain-config.xml<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/param-value<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/init-param<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/servlet<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The trouble however, is that the Struts Tiles plugin that shipped with 1.3 didn&#8217;t change from 1.2. It was written to automatically replace the default RequestProcessor and its chain of command. I&#8217;m pretty sure this was supposed to be a convenience, so that to use the Tiles plugin, all you had to do was flip a switch, and it would figure out its own hooks into Struts&#8230; because this is how the Struts Tiles plugin works; it essentially overrides and customizes the RequestProcessor so forwards goto it, rather than to some JSP file or somerthing somewhere. You can see how it&#8217;s doing this overriding by looking at the method <a href="http://svn.apache.org/repos/asf/struts/struts1/trunk/tiles/src/main/java/org/apache/struts/tiles/TilesPlugin.java">TilesPlugin.initRequestProcessorClass</a>; which is actually a little interesting, because it&#8217;s not mucking with any XML. But that&#8217;s all you really have to do, <i>usually</i>.</p>
<p><i>However</i>, and this is why I&#8217;m posting this; if you have a custom chain-config.xml already in place that was based on the chain-config.xml in the struts-core JAR, then your ActionForwards going to Tiles layouts aren&#8217;t going to lookup correctly. For example, when Struts tries to goto the ActionForward &#8220;page.index&#8221;, we get the following exception because normally ActionForwards would goto a page like &#8220;/index.jsp&#8221;.</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">WARNING: Unhandled exception
java.lang.IllegalArgumentException: Path page.index does not start with a &quot;/&quot; character
	at org.apache.catalina.core.ApplicationContext.getRequestDispatcher(ApplicationContext.java:374)
	at org.apache.catalina.core.ApplicationContextFacade.getRequestDispatcher(ApplicationContextFacade.java:196)
	at org.apache.struts.chain.commands.servlet.PerformForward.handleAsForward(PerformForward.java:107)
	at org.apache.struts.chain.commands.servlet.PerformForward.perform(PerformForward.java:96)
	at org.apache.struts.chain.commands.AbstractPerformForward.execute(AbstractPerformForward.java:54)
	at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:305)
	at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
	at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
	at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
        ...</pre></div></div>

<p>As far as cryptic errors go, this one is pretty far up there, and unless you actually know how Tiles works, it&#8217;s going to be a huge pain to debug. The remedy is actually to base your chain-config.xml file off of Tiles&#8217; own <a href="http://svn.apache.org/repos/asf/struts/struts1/trunk/tiles/src/main/resources/org/apache/struts/tiles/chain-config.xml">chain-config.xml</a>. And in it you can see how at the end it calls <a href="http://svn.apache.org/repos/asf/struts/struts1/trunk/tiles/src/main/java/org/apache/struts/tiles/commands/TilesPreProcessor.java">TilesPreProcessor</a> right before it performs the forward.</p>
<p>The Tiles documentation indeed says <a href="http://struts.apache.org/1.x/struts-tiles/installation.html">you need to do this</a> &#8212; but hardly anyone ever does, because everything will work unless you customize the request processor; and hardly any books or sites out there will tell you to do it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.philihp.com/blog/2011/adding-tiles-to-a-struts-1-3-project-with-a-custom-request-processor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wicket Homepage Redirecting</title>
		<link>http://www.philihp.com/blog/2010/wicket-homepage-redirecting/</link>
		<comments>http://www.philihp.com/blog/2010/wicket-homepage-redirecting/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 19:28:04 +0000</pubDate>
		<dc:creator>philihp</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://www.philihp.com/blog/?p=588</guid>
		<description><![CDATA[With the Wicket Java Web framework where a lot of magic happens behind the scenes, and almost no XML needs to be configured. Most of it is done with Java. It has a lot of pretty cool features. I just came across this one. In the init setup of your class that extends WebApplication, you [...]]]></description>
			<content:encoded><![CDATA[<p>With the <a href="http://wicket.apache.org/">Wicket</a> Java Web framework where a lot of magic happens behind the scenes, and almost no XML needs to be configured. Most of it is done with Java. It has a lot of pretty cool features. I just came across this one.</p>
<p>In the init setup of your class that extends <a href="http://wicket.apache.org/apidocs/1.4/org/apache/wicket/protocol/http/WebApplication.html">WebApplication</a>, you can &#8220;mount&#8221; your pages at paths, like this:</p>
<pre name="code" class="java">
@Override
protected void init() {
	super.init();
	mountBookmarkablePage("/search", SearchPage.class);
}
</pre>
<p>So when you goto http://somewhere.com/somecontext/search, it gives you the SearchPage class.</p>
<p>You can also specify a HomePage index, like this:</p>
<pre name="code" class="java">
public Class<? extends Page> getHomePage() {
	return IndexPage.class;
}
</pre>
<p>Then when you goto http://somewhere.com/somecontext/, it gives you the IndexPage class.</p>
<p>The cool subtle thing here is what happens when you do them both; i.e. you mount SearchPage to /search, and you override getHomePage to return SearchPage.class. Do this, and when you goto http://somewhere.com/somecontext/, it will redirect to http://somewhere.com/somecontext/search!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.philihp.com/blog/2010/wicket-homepage-redirecting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Static Java List Instantiation</title>
		<link>http://www.philihp.com/blog/2009/static-java-list-instantiation/</link>
		<comments>http://www.philihp.com/blog/2009/static-java-list-instantiation/#comments</comments>
		<pubDate>Sat, 16 May 2009 18:54:03 +0000</pubDate>
		<dc:creator>philihp</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Example]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[List]]></category>

		<guid isPermaLink="false">http://www.philihp.com/blog/?p=417</guid>
		<description><![CDATA[But it recently occurred to me that with variable-length methods, I can simply call asList like this:

<pre>List&#60;String&#62; strings = Arrays.asList(foo","bar");</pre>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been out of the loop on straight Java programming for a while, so this is probably obvious to a lot of people, and has been for a long time. But on the off chance that I&#8217;m not the only other idiot out there, I&#8217;ll post this.</p>
<p>The old way of instantiating a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/List.html">List</a> in Java was like this:</p>
<pre name="code" class="java:nocontrols">List strings = Arrays.asList(new String[]{"foo","bar"});</pre>
<p>In Java 5, templates were introduced, so I had to change to doing this:</p>
<pre name="code" class="java:nocontrols">List&lt;String&gt; strings = Arrays.asList(new String[]{"foo","bar"});</pre>
<p>It just occurred to me that with variable-length methods, I can simply call asList like this:</p>
<pre name="code" class="java:nocontrols">List&lt;String&gt; strings = Arrays.asList("foo","bar");</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.philihp.com/blog/2009/static-java-list-instantiation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

