Thanks, Jacques and Mathieu. Verified the fix on the local machine, the system is working fine now.
Thanks & Regards -- Deepak Nigam HotWax Systems Pvt. Ltd. On Tue, Aug 28, 2018 at 9:51 PM Jacques Le Roux < [email protected]> wrote: > Hi, > > I confirm this issue which can easily be reproduced in trunk and locally. > > The problem is r1838081 prevents to serialise requests. > > Like in ordermgr/control/updateCheckoutOptions/quickcheckout where > updateCheckoutOptions and quickcheckout are serialised to update the check > out with > updateCheckoutOptions and then get back to the screen with quickcheckout > > It's fixed at r1839451 using last Mathieu's patch in OFBIZ-10438 > > Jacques > > > Le 20/08/2018 à 06:25, deepak nigam a écrit : > > Hi Shi/Rishi, > > > > I was using the trunk downloaded from GitHub ( > > https://github.com/apache/ofbiz-framework). I will reverify this issue > on > > SVN trunk and will let you know the details. > > > > On Mon, Aug 20, 2018 at 1:37 AM Shi Jinghai <[email protected]> > wrote: > > > >> Hi Deepak, > >> > >> As Rishi suggested, could you please reopen OFBIZ-10438 or create a new > >> jira for the bug you mentioned here? > >> > >> I cannot reproduce it in my local and online trunk demo environments, I > >> guess my test case is not the same as yours. > >> > >> Thanks, > >> > >> Shi Jinghai > >> > >> -----邮件原件----- > >> 发件人: Rishi Solanki [mailto:[email protected]] > >> 发送时间: 2018年8月17日 21:24 > >> 收件人: [email protected] > >> 抄送: [email protected] > >> 主题: Re: svn commit: r1838081 - in > /ofbiz/ofbiz-framework/trunk/framework: > >> base/src/main/java/org/apache/ofbiz/base/util/collections/ > >> base/src/test/java/org/apache/ofbiz/base/collections/ webapp/config/ > >> webapp/dtd/ webapp/src/main/java/org/apache/ofbiz/weba... > >> > >> Deepak, > >> > >> Thanks for reporting the issue, can you please create Jira ticket and > add > >> details (images are not coming at mailing list) with logs if possible? > >> > >> > >> > >> Rishi Solanki > >> Sr Manager, Enterprise Software Development > >> HotWax Systems Pvt. Ltd. > >> Direct: +91-9893287847 > >> http://www.hotwaxsystems.com > >> www.hotwax.co > >> > >> On Fri, Aug 17, 2018 at 6:32 PM, deepak nigam < > [email protected]> > >> wrote: > >> > >>> I am using OFBiz trunk and on creating an order from backend and > getting > >>> error screens while adding an item to cart and selecting shipping > >> methods. > >>> Please find the attached images for your reference. > >>> > >>> On further investigation, I found that on reverting this commit things > >> are > >>> working fine. Can we verify this commit once more? > >>> > >>> On Wed, Aug 15, 2018 at 5:15 PM <[email protected]> wrote: > >>> > >>>> Author: shijh > >>>> Date: Wed Aug 15 11:45:45 2018 > >>>> New Revision: 1838081 > >>>> > >>>> URL: http://svn.apache.org/viewvc?rev=1838081&view=rev > >>>> Log: > >>>> Implemented: Add method attribute to request-map to controll a uri can > >> be > >>>> called GET or POST only > >>>> OFBIZ-10438 > >>>> > >>>> Thanks: Mathieu Lirzin for the contribution. > >>>> > >>>> Added: > >>>> ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> org/apache/ofbiz/base/util/collections/MultivaluedMapContext.java > >>>> (with props) > >>>> ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> > org/apache/ofbiz/base/util/collections/MultivaluedMapContextAdapter.java > >>>> (with props) > >>>> ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> org/apache/ofbiz/base/collections/ > >>>> ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> > org/apache/ofbiz/base/collections/MultivaluedMapContextAdapterTests.java > >>>> (with props) > >>>> ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> org/apache/ofbiz/base/collections/MultivaluedMapContextTests.java > >>>> (with props) > >>>> ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java > >>>> (with props) > >>>> ofbiz/ofbiz-framework/trunk/framework/webapp/src/test/ > >>>> java/org/apache/ofbiz/webapp/control/RequestHandlerTests.java (with > >>>> props) > >>>> Modified: > >>>> ofbiz/ofbiz-framework/trunk/framework/webapp/config/ > >>>> WebappUiLabels.xml > >>>> ofbiz/ofbiz-framework/trunk/framework/webapp/dtd/site-conf.xsd > >>>> ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java > >>>> ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/ControlServlet.java > >>>> ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/RequestHandler.java > >>>> > >>>> Added: ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> org/apache/ofbiz/base/util/collections/MultivaluedMapContext.java > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/base/src/main/java/org/apache/ofbiz/base/util/collections/ > >>>> MultivaluedMapContext.java?rev=1838081&view=auto > >>>> ============================================================ > >>>> ================== > >>>> --- ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> org/apache/ofbiz/base/util/collections/MultivaluedMapContext.java > >> (added) > >>>> +++ ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> org/apache/ofbiz/base/util/collections/MultivaluedMapContext.java Wed > >>>> Aug 15 11:45:45 2018 > >>>> @@ -0,0 +1,87 @@ > >>>> +/********************************************************** > >>>> ********************* > >>>> + * Licensed to the Apache Software Foundation (ASF) under one > >>>> + * or more contributor license agreements. See the NOTICE file > >>>> + * distributed with this work for additional information > >>>> + * regarding copyright ownership. The ASF licenses this file > >>>> + * to you 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.ofbiz.base.util.collections; > >>>> + > >>>> +import java.util.LinkedList; > >>>> +import java.util.List; > >>>> + > >>>> +/** > >>>> + * MultivaluedMap Context > >>>> + * > >>>> + * A MapContext which handles multiple values for the same key. > >>>> + */ > >>>> +public class MultivaluedMapContext<K, V> extends MapContext<K, > >> List<V>> { > >>>> + > >>>> + public static final String module = MultivaluedMapContext.class. > >>>> getName(); > >>>> + > >>>> + /** > >>>> + * Create a multi-value map initialized with one context > >>>> + */ > >>>> + public MultivaluedMapContext() { > >>>> + push(); > >>>> + } > >>>> + > >>>> + /** > >>>> + * Associate {@code key} with the single value {@code value}. > >>>> + * If other values are already associated with {@code key} then > >>>> override them. > >>>> + * > >>>> + * @param key the key to associate {@code value} with > >>>> + * @param value the value to add to the context > >>>> + */ > >>>> + public void putSingle(K key, V value) { > >>>> + List<V> box = new LinkedList<>(); > >>>> + box.add(value); > >>>> + put(key, box); > >>>> + } > >>>> + > >>>> + /** > >>>> + * Associate {@code key} with the single value {@code value}. > >>>> + * If other values are already associated with {@code key}, > >>>> + * then add {@code value} to them. > >>>> + * > >>>> + * @param key the key to associate {@code value} with > >>>> + * @param value the value to add to the context > >>>> + */ > >>>> + public void add(K key, V value) { > >>>> + List<V> cur = contexts.getFirst().get(key); > >>>> + if (cur == null) { > >>>> + cur = new LinkedList<>(); > >>>> + /* if this method is called after a context switch, copy > >> the > >>>> previous values > >>>> + in current context to not mask them. */ > >>>> + List<V> old = get(key); > >>>> + if (old != null) { > >>>> + cur.addAll(old); > >>>> + } > >>>> + } > >>>> + cur.add(value); > >>>> + put(key, cur); > >>>> + } > >>>> + > >>>> + /** > >>>> + * Get the first value contained in the list of values associated > >>>> with {@code key}. > >>>> + * > >>>> + * @param key a candidate key > >>>> + * @return the first value associated with {@code key} or null if > >> no > >>>> value > >>>> + * is associated with it. > >>>> + */ > >>>> + public V getFirst(Object key) { > >>>> + List<V> res = get(key); > >>>> + return res == null ? null : res.get(0); > >>>> + } > >>>> +} > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> org/apache/ofbiz/base/util/collections/MultivaluedMapContext.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:eol-style = native > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> org/apache/ofbiz/base/util/collections/MultivaluedMapContext.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:keywords = Date Rev Author URL Id > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> org/apache/ofbiz/base/util/collections/MultivaluedMapContext.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:mime-type = text/plain > >>>> > >>>> Added: ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> > org/apache/ofbiz/base/util/collections/MultivaluedMapContextAdapter.java > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/base/src/main/java/org/apache/ofbiz/base/util/collections/ > >>>> MultivaluedMapContextAdapter.java?rev=1838081&view=auto > >>>> ============================================================ > >>>> ================== > >>>> --- ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> > org/apache/ofbiz/base/util/collections/MultivaluedMapContextAdapter.java > >>>> (added) > >>>> +++ ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> > org/apache/ofbiz/base/util/collections/MultivaluedMapContextAdapter.java > >>>> Wed Aug 15 11:45:45 2018 > >>>> @@ -0,0 +1,103 @@ > >>>> +/********************************************************** > >>>> ********************* > >>>> + * Licensed to the Apache Software Foundation (ASF) under one > >>>> + * or more contributor license agreements. See the NOTICE file > >>>> + * distributed with this work for additional information > >>>> + * regarding copyright ownership. The ASF licenses this file > >>>> + * to you 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.ofbiz.base.util.collections; > >>>> + > >>>> +import java.util.Collection; > >>>> +import java.util.Map; > >>>> +import java.util.Set; > >>>> +import java.util.stream.Collectors; > >>>> + > >>>> +// Adapter which allows viewing a multi-value map as a single-value > >> map. > >>>> +public class MultivaluedMapContextAdapter<K, V> implements Map<K, V> > { > >>>> + private MultivaluedMapContext<K, V> adaptee; > >>>> + > >>>> + public MultivaluedMapContextAdapter(MultivaluedMapContext<K, V> > >>>> adaptee) { > >>>> + this.adaptee = adaptee; > >>>> + } > >>>> + > >>>> + @Override > >>>> + public int size() { > >>>> + return adaptee.size(); > >>>> + } > >>>> + > >>>> + @Override > >>>> + public boolean isEmpty() { > >>>> + return adaptee.isEmpty(); > >>>> + } > >>>> + > >>>> + @Override > >>>> + public boolean containsKey(Object key) { > >>>> + return adaptee.containsKey(key); > >>>> + } > >>>> + > >>>> + @Override > >>>> + public boolean containsValue(Object value) { > >>>> + return adaptee.values().stream() > >>>> + .map(l -> l.get(0)) > >>>> + .anyMatch(value::equals); > >>>> + } > >>>> + > >>>> + @Override > >>>> + public V get(Object key) { > >>>> + return adaptee.getFirst(key); > >>>> + } > >>>> + > >>>> + @Override > >>>> + public V put(K key, V value) { > >>>> + V prev = get(key); > >>>> + adaptee.putSingle(key, value); > >>>> + return prev; > >>>> + } > >>>> + > >>>> + @Override > >>>> + public V remove(Object key) { > >>>> + V prev = get(key); > >>>> + adaptee.remove(key); > >>>> + return prev; > >>>> + } > >>>> + > >>>> + @Override > >>>> + public void putAll(Map<? extends K, ? extends V> m) { > >>>> + m.forEach(adaptee::putSingle); > >>>> + } > >>>> + > >>>> + @Override > >>>> + public void clear() { > >>>> + adaptee.clear(); > >>>> + } > >>>> + > >>>> + @Override > >>>> + public Set<K> keySet() { > >>>> + return adaptee.keySet(); > >>>> + } > >>>> + > >>>> + @Override > >>>> + public Collection<V> values() { > >>>> + return adaptee.values().stream() > >>>> + .map(l -> l.get(0)) > >>>> + .collect(Collectors.toList()); > >>>> + } > >>>> + > >>>> + @Override > >>>> + public Set<Entry<K, V>> entrySet() { > >>>> + return adaptee.keySet().stream() > >>>> + .collect(Collectors.toMap(k -> k, k -> get(k))) > >>>> + .entrySet(); > >>>> + } > >>>> +} > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> > org/apache/ofbiz/base/util/collections/MultivaluedMapContextAdapter.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:eol-style = native > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> > org/apache/ofbiz/base/util/collections/MultivaluedMapContextAdapter.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:keywords = Date Rev Author URL Id > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/ > >>>> > org/apache/ofbiz/base/util/collections/MultivaluedMapContextAdapter.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:mime-type = text/plain > >>>> > >>>> Added: ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> > org/apache/ofbiz/base/collections/MultivaluedMapContextAdapterTests.java > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/base/src/test/java/org/apache/ofbiz/base/collections/ > >>>> MultivaluedMapContextAdapterTests.java?rev=1838081&view=auto > >>>> ============================================================ > >>>> ================== > >>>> --- ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> > org/apache/ofbiz/base/collections/MultivaluedMapContextAdapterTests.java > >>>> (added) > >>>> +++ ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> > org/apache/ofbiz/base/collections/MultivaluedMapContextAdapterTests.java > >>>> Wed Aug 15 11:45:45 2018 > >>>> @@ -0,0 +1,70 @@ > >>>> +/********************************************************** > >>>> ********************* > >>>> + * Licensed to the Apache Software Foundation (ASF) under one > >>>> + * or more contributor license agreements. See the NOTICE file > >>>> + * distributed with this work for additional information > >>>> + * regarding copyright ownership. The ASF licenses this file > >>>> + * to you 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.ofbiz.base.collections; > >>>> + > >>>> +import static org.hamcrest.CoreMatchers.hasItems; > >>>> +import static org.hamcrest.CoreMatchers.is; > >>>> +import static org.junit.Assert.assertEquals; > >>>> +import static org.junit.Assert.assertFalse; > >>>> +import static org.junit.Assert.assertThat; > >>>> +import static org.junit.Assert.assertTrue; > >>>> + > >>>> +import java.util.HashMap; > >>>> + > >>>> +import org.apache.ofbiz.base.util.collections.MultivaluedMapContext; > >>>> +import org.apache.ofbiz.base.util.collections. > >>>> MultivaluedMapContextAdapter; > >>>> +import org.junit.Before; > >>>> +import org.junit.Test; > >>>> + > >>>> +public class MultivaluedMapContextAdapterTests { > >>>> + private MultivaluedMapContext<String, Integer> adaptee; > >>>> + private MultivaluedMapContextAdapter<String, Integer> adapter; > >>>> + > >>>> + @Before > >>>> + public void setUp() throws Exception { > >>>> + adaptee = new MultivaluedMapContext<>(); > >>>> + adaptee.add("foo", 0); > >>>> + adaptee.add("foo", 1); > >>>> + adaptee.add("foo", 2); > >>>> + adaptee.add("bar", 3); > >>>> + adapter = new MultivaluedMapContextAdapter<>(adaptee); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void containsValueBasic() { > >>>> + assertTrue(adapter.containsValue(0)); > >>>> + assertFalse(adapter.containsValue(1)); > >>>> + assertFalse(adapter.containsValue(2)); > >>>> + assertTrue(adapter.containsValue(3)); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void valuesBasic() { > >>>> + assertThat(adapter.values(), hasItems(0, 3)); > >>>> + assertThat(adapter.values().size(), is(2)); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void entrySetBasic() { > >>>> + HashMap<String, Integer> expected = new HashMap<>(); > >>>> + expected.put("foo", 0); > >>>> + expected.put("bar", 3); > >>>> + assertEquals(expected.entrySet(), adapter.entrySet()); > >>>> + } > >>>> +} > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> > org/apache/ofbiz/base/collections/MultivaluedMapContextAdapterTests.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:eol-style = native > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> > org/apache/ofbiz/base/collections/MultivaluedMapContextAdapterTests.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:keywords = Date Rev Author URL Id > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> > org/apache/ofbiz/base/collections/MultivaluedMapContextAdapterTests.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:mime-type = text/plain > >>>> > >>>> Added: ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> org/apache/ofbiz/base/collections/MultivaluedMapContextTests.java > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/base/src/test/java/org/apache/ofbiz/base/collections/ > >>>> MultivaluedMapContextTests.java?rev=1838081&view=auto > >>>> ============================================================ > >>>> ================== > >>>> --- ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> org/apache/ofbiz/base/collections/MultivaluedMapContextTests.java > >> (added) > >>>> +++ ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> org/apache/ofbiz/base/collections/MultivaluedMapContextTests.java Wed > >>>> Aug 15 11:45:45 2018 > >>>> @@ -0,0 +1,82 @@ > >>>> +/********************************************************** > >>>> ********************* > >>>> + * Licensed to the Apache Software Foundation (ASF) under one > >>>> + * or more contributor license agreements. See the NOTICE file > >>>> + * distributed with this work for additional information > >>>> + * regarding copyright ownership. The ASF licenses this file > >>>> + * to you 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.ofbiz.base.collections; > >>>> + > >>>> +import static org.hamcrest.CoreMatchers.both; > >>>> +import static org.hamcrest.CoreMatchers.hasItem; > >>>> +import static org.hamcrest.CoreMatchers.hasItems; > >>>> +import static org.hamcrest.CoreMatchers.is; > >>>> +import static org.hamcrest.CoreMatchers.not; > >>>> +import static org.hamcrest.CoreMatchers.nullValue; > >>>> +import static org.junit.Assert.assertThat; > >>>> + > >>>> +import org.apache.ofbiz.base.util.collections.MultivaluedMapContext; > >>>> +import org.junit.Before; > >>>> +import org.junit.Test; > >>>> + > >>>> +public class MultivaluedMapContextTests { > >>>> + private MultivaluedMapContext<String, Integer> m; > >>>> + > >>>> + @Before > >>>> + public void setUp() throws Exception { > >>>> + m = new MultivaluedMapContext<>(); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void getEmpty() { > >>>> + assertThat(m.get("foo"), is(nullValue())); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void putSingleBasic() { > >>>> + m.putSingle("foo", 0); > >>>> + assertThat(m.get("foo"), hasItem(0)); > >>>> + m.putSingle("foo", 1); > >>>> + assertThat(m.get("foo"), > >> both(hasItem(1)).and(not(hasItem(0)))); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void addBasic() { > >>>> + m.add("foo", 0); > >>>> + assertThat(m.get("foo"), hasItem(0)); > >>>> + m.add("foo", 1); > >>>> + assertThat(m.get("foo"), hasItems(0, 1)); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void addWithPreviousContext() { > >>>> + m.add("foo", 0); > >>>> + m.push(); > >>>> + assertThat(m.get("foo"), hasItem(0)); > >>>> + m.add("foo", 1); > >>>> + assertThat(m.get("foo"), hasItems(0, 1)); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void getFirstBasic() { > >>>> + m.add("foo", 0); > >>>> + m.add("foo", 1); > >>>> + assertThat(m.getFirst("foo"), is(0)); > >>>> + } > >>>> + > >>>> + @Test > >>>> + public void getFirstEmpty() { > >>>> + assertThat(m.getFirst("foo"), is(nullValue())); > >>>> + } > >>>> +} > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> org/apache/ofbiz/base/collections/MultivaluedMapContextTests.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:eol-style = native > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> org/apache/ofbiz/base/collections/MultivaluedMapContextTests.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:keywords = Date Rev Author URL Id > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/base/src/test/java/ > >>>> org/apache/ofbiz/base/collections/MultivaluedMapContextTests.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:mime-type = text/plain > >>>> > >>>> Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/config/ > >>>> WebappUiLabels.xml > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/webapp/config/WebappUiLabels.xml?rev= > >>>> 1838081&r1=1838080&r2=1838081&view=diff > >>>> ============================================================ > >>>> ================== > >>>> --- > >> ofbiz/ofbiz-framework/trunk/framework/webapp/config/WebappUiLabels.xml > >>>> (original) > >>>> +++ > >> ofbiz/ofbiz-framework/trunk/framework/webapp/config/WebappUiLabels.xml > >>>> Wed Aug 15 11:45:45 2018 > >>>> @@ -339,4 +339,8 @@ > >>>> <value xml:lang="zh">æ²¡æœ‰å®Œæˆ äº‹ä»¶</value> > >>>> <value xml:lang="zh-TW">æ²’æœ‰å®Œæˆ äº‹ä»¶</value> > >>>> </property> > >>>> + <property key="RequestMethodNotMatchConfig"> > >>>> + <value xml:lang="en">[{0}] cannot be called by [{1}] > >>>> method.</value> > >>>> + <value xml:lang="zh">[{0}]ä¸ > 能用[{1}]方法请求。</value> > >>>> + </property> > >>>> </resource> > >>>> > >>>> Modified: > ofbiz/ofbiz-framework/trunk/framework/webapp/dtd/site-conf.xsd > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/webapp/dtd/site-conf.xsd?rev=1838081&r1= > >>>> 1838080&r2=1838081&view=diff > >>>> ============================================================ > >>>> ================== > >>>> --- ofbiz/ofbiz-framework/trunk/framework/webapp/dtd/site-conf.xsd > >>>> (original) > >>>> +++ ofbiz/ofbiz-framework/trunk/framework/webapp/dtd/site-conf.xsd Wed > >>>> Aug 15 11:45:45 2018 > >>>> @@ -216,6 +216,24 @@ under the License. > >>>> </xs:documentation> > >>>> </xs:annotation> > >>>> </xs:attribute> > >>>> + <xs:attribute name="method" use="optional" default="all"> > >>>> + <xs:annotation> > >>>> + <xs:documentation> > >>>> + The HTTP of this request. This will be the HTTP > >>>> method used to access the request. > >>>> + </xs:documentation> > >>>> + </xs:annotation> > >>>> + <xs:simpleType> > >>>> + <xs:restriction base="xs:token"> > >>>> + <xs:enumeration value="get"/> > >>>> + <xs:enumeration value="post"/> > >>>> + <xs:enumeration value="put"/> > >>>> + <xs:enumeration value="delete"/> > >>>> + <xs:enumeration value="patch"/> > >>>> + <xs:enumeration value="options"/> > >>>> + <xs:enumeration value="all"/> > >>>> + </xs:restriction> > >>>> + </xs:simpleType> > >>>> + </xs:attribute> > >>>> <xs:attribute type="xs:boolean" name="edit" default="true"> > >>>> <xs:annotation> > >>>> <xs:documentation> > >>>> > >>>> Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/webapp/src/main/java/org/apache/ofbiz/webapp/ > >>>> > control/ConfigXMLReader.java?rev=1838081&r1=1838080&r2=1838081&view=diff > >>>> ============================================================ > >>>> ================== > >>>> --- ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java (original) > >>>> +++ ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java Wed Aug 15 > >>>> 11:45:45 2018 > >>>> @@ -49,6 +49,8 @@ import org.apache.ofbiz.base.util.UtilVa > >>>> import org.apache.ofbiz.base.util.UtilXml; > >>>> import org.apache.ofbiz.base.util.cache.UtilCache; > >>>> import org.apache.ofbiz.base.util.collections.MapContext; > >>>> +import org.apache.ofbiz.base.util.collections.MultivaluedMapContext; > >>>> +import org.apache.ofbiz.base.util.collections. > >>>> MultivaluedMapContextAdapter; > >>>> import org.w3c.dom.Document; > >>>> import org.w3c.dom.Element; > >>>> > >>>> @@ -192,7 +194,7 @@ public class ConfigXMLReader { > >>>> private Map<String, Event> beforeLogoutEventList = new > >>>> LinkedHashMap<String, Event>(); > >>>> private Map<String, String> eventHandlerMap = new > >>>> HashMap<String, String>(); > >>>> private Map<String, String> viewHandlerMap = new > >> HashMap<String, > >>>> String>(); > >>>> - private Map<String, RequestMap> requestMapMap = new > >>>> HashMap<String, RequestMap>(); > >>>> + private MultivaluedMapContext<String, RequestMap> > requestMapMap > >>>> = new MultivaluedMapContext<>(); > >>>> private Map<String, ViewMap> viewMapMap = new > HashMap<String, > >>>> ViewMap>(); > >>>> > >>>> public ControllerConfig(URL url) throws > >>>> WebAppConfigurationException { > >>>> @@ -276,11 +278,16 @@ public class ConfigXMLReader { > >>>> return getIncludes(ccfg -> ccfg.protectView); > >>>> } > >>>> > >>>> + // XXX: Keep it for backward compatibility until moving > >>>> everything to 鈥榞etRequestMapMultiMap鈥�. > >>>> public Map<String, RequestMap> getRequestMapMap() throws > >>>> WebAppConfigurationException { > >>>> - MapContext<String, RequestMap> result = new > MapContext<>(); > >>>> + return new MultivaluedMapContextAdapter<> > >>>> (getRequestMapMultiMap()); > >>>> + } > >>>> + > >>>> + public MultivaluedMapContext<String, RequestMap> > >>>> getRequestMapMultiMap() throws WebAppConfigurationException { > >>>> + MultivaluedMapContext<String, RequestMap> result = new > >>>> MultivaluedMapContext<>(); > >>>> for (URL includeLocation : includes) { > >>>> ControllerConfig controllerConfig = > >> getControllerConfig( > >>>> includeLocation); > >>>> - result.push(controllerConfig.getRequestMapMap()); > >>>> + > result.push(controllerConfig.getRequestMapMultiMap()); > >>>> } > >>>> result.push(requestMapMap); > >>>> return result; > >>>> @@ -403,7 +410,7 @@ public class ConfigXMLReader { > >>>> private void loadRequestMap(Element root) { > >>>> for (Element requestMapElement : > >>>> UtilXml.childElementList(root, "request-map")) { > >>>> RequestMap requestMap = new > >>>> RequestMap(requestMapElement); > >>>> - this.requestMapMap.put(requestMap.uri, requestMap); > >>>> + this.requestMapMap.add(requestMap.uri, requestMap); > >>>> } > >>>> } > >>>> > >>>> @@ -450,6 +457,7 @@ public class ConfigXMLReader { > >>>> > >>>> public static class RequestMap { > >>>> public String uri; > >>>> + public String method; > >>>> public boolean edit = true; > >>>> public boolean trackVisit = true; > >>>> public boolean trackServerHit = true; > >>>> @@ -466,6 +474,7 @@ public class ConfigXMLReader { > >>>> public RequestMap(Element requestMapElement) { > >>>> // Get the URI info > >>>> this.uri = requestMapElement.getAttribute("uri"); > >>>> + this.method = requestMapElement.getAttribute("method"); > >>>> this.edit = !"false".equals(requestMapElement. > >>>> getAttribute("edit")); > >>>> this.trackServerHit = !"false".equals(requestMapElement. > >>>> getAttribute("track-serverhit")); > >>>> this.trackVisit = !"false".equals(requestMapElement. > >>>> getAttribute("track-visit")); > >>>> > >>>> Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/ControlServlet.java > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/webapp/src/main/java/org/apache/ofbiz/webapp/ > >>>> > control/ControlServlet.java?rev=1838081&r1=1838080&r2=1838081&view=diff > >>>> ============================================================ > >>>> ================== > >>>> --- ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/ControlServlet.java (original) > >>>> +++ ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/ControlServlet.java Wed Aug 15 > >>>> 11:45:45 2018 > >>>> @@ -211,6 +211,12 @@ public class ControlServlet extends Http > >>>> try { > >>>> // the ServerHitBin call for the event is done inside > the > >>>> doRequest method > >>>> requestHandler.doRequest(request, response, null, > >>>> userLogin, delegator); > >>>> + } catch (MethodNotAllowedException e) { > >>>> + response.setContentType("text/plain"); > >>>> + > >> response.setCharacterEncoding(request.getCharacterEncoding() > >>>> ); > >>>> + response.setStatus(HttpServletResponse.SC_METHOD_ > >>>> NOT_ALLOWED); > >>>> + response.getWriter().print(e.getMessage()); > >>>> + Debug.logError(e.getMessage(), module); > >>>> } catch (RequestHandlerException e) { > >>>> Throwable throwable = e.getNested() != null ? > e.getNested() > >>>> : e; > >>>> if (throwable instanceof IOException) { > >>>> > >>>> Added: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ > >>>> MethodNotAllowedException.java?rev=1838081&view=auto > >>>> ============================================================ > >>>> ================== > >>>> --- ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java > >>>> (added) > >>>> +++ ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java > Wed > >>>> Aug 15 11:45:45 2018 > >>>> @@ -0,0 +1,26 @@ > >>>> +/********************************************************** > >>>> ********************* > >>>> + * Licensed to the Apache Software Foundation (ASF) under one > >>>> + * or more contributor license agreements. See the NOTICE file > >>>> + * distributed with this work for additional information > >>>> + * regarding copyright ownership. The ASF licenses this file > >>>> + * to you 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.ofbiz.webapp.control; > >>>> + > >>>> +@SuppressWarnings("serial") > >>>> +public class MethodNotAllowedException extends > RequestHandlerException > >> { > >>>> + MethodNotAllowedException(String str) { > >>>> + super(str); > >>>> + } > >>>> +} > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:eol-style = native > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:keywords = Date Rev Author URL Id > >>>> > >>>> Propchange: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java > >>>> ------------------------------------------------------------ > >>>> ------------------ > >>>> svn:mime-type = text/plain > >>>> > >>>> Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/RequestHandler.java > >>>> URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/ > >>>> framework/webapp/src/main/java/org/apache/ofbiz/webapp/ > >>>> > control/RequestHandler.java?rev=1838081&r1=1838080&r2=1838081&view=diff > >>>> ============================================================ > >>>> ================== > >>>> --- ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/RequestHandler.java (original) > >>>> +++ ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/ > >>>> java/org/apache/ofbiz/webapp/control/RequestHandler.java Wed Aug 15 > >>>> 11:45:45 2018 > >>>> @@ -24,11 +24,15 @@ import java.io.IOException; > >>>> import java.io.Serializable; > >>>> import java.net.URL; > >>>> import java.security.cert.X509Certificate; > >>>> + > >>>> +import java.util.Collection; > >>>> +import java.util.Collections; > >>>> import java.util.Enumeration; > >>>> import java.util.HashMap; > >>>> import java.util.List; > >>>> import java.util.Locale; > >>>> import java.util.Map; > >>>> +import java.util.Optional; > >>>> > >>>> import javax.servlet.ServletContext; > >>>> import javax.servlet.http.HttpServletRequest; > >>>> @@ -45,12 +49,14 @@ import org.apache.ofbiz.base.util.UtilMi > >>>> import org.apache.ofbiz.base.util.UtilObject; > >>>> import org.apache.ofbiz.base.util.UtilProperties; > >>>> import org.apache.ofbiz.base.util.UtilValidate; > >>>> +import org.apache.ofbiz.base.util.collections.MultivaluedMapContext; > >>>> import org.apache.ofbiz.entity.Delegator; > >>>> import org.apache.ofbiz.entity.GenericEntityException; > >>>> import org.apache.ofbiz.entity.GenericValue; > >>>> import org.apache.ofbiz.entity.util.EntityQuery; > >>>> import org.apache.ofbiz.entity.util.EntityUtilProperties; > >>>> import org.apache.ofbiz.webapp.OfbizUrlBuilder; > >>>> +import org.apache.ofbiz.webapp.control.ConfigXMLReader.RequestMap; > >>>> import org.apache.ofbiz.webapp.event.EventFactory; > >>>> import org.apache.ofbiz.webapp.event.EventHandler; > >>>> import org.apache.ofbiz.webapp.event.EventHandlerException; > >>>> @@ -68,12 +74,74 @@ import org.apache.ofbiz.widget.model.The > >>>> public class RequestHandler { > >>>> > >>>> public static final String module = > RequestHandler.class.getName(); > >>>> - private final String defaultStatusCodeString = UtilProperties. > >>>> getPropertyValue("requestHandler", "status-code", "302"); > >>>> + private final static String defaultStatusCodeString = > >>>> + UtilProperties.getPropertyValue("requestHandler", > >>>> "status-code", "302"); > >>>> private final ViewFactory viewFactory; > >>>> private final EventFactory eventFactory; > >>>> private final URL controllerConfigURL; > >>>> private final boolean trackServerHit; > >>>> private final boolean trackVisit; > >>>> + private ControllerConfig ccfg; > >>>> + > >>>> + static class ControllerConfig { > >>>> + private final MultivaluedMapContext<String, RequestMap> > >>>> requestMapMap; > >>>> + private final Map<String, ConfigXMLReader.ViewMap> > viewMapMap; > >>>> + private String statusCodeString; > >>>> + private final String defaultRequest; > >>>> + private final Map<String, ConfigXMLReader.Event> > >>>> firstVisitEventList; > >>>> + private final Map<String, ConfigXMLReader.Event> > >>>> preprocessorEventList; > >>>> + private final Map<String, ConfigXMLReader.Event> > >>>> postprocessorEventList; > >>>> + private final String protectView; > >>>> + > >>>> + ControllerConfig(ConfigXMLReader.ControllerConfig ccfg) > throws > >>>> WebAppConfigurationException { > >>>> + preprocessorEventList = ccfg.getPreprocessorEventList(); > >>>> + postprocessorEventList = > ccfg.getPostprocessorEventList(); > >>>> + requestMapMap = ccfg.getRequestMapMultiMap(); > >>>> + viewMapMap = ccfg.getViewMapMap(); > >>>> + defaultRequest = ccfg.getDefaultRequest(); > >>>> + firstVisitEventList = ccfg.getFirstVisitEventList(); > >>>> + protectView = ccfg.getProtectView(); > >>>> + > >>>> + String status = ccfg.getStatusCode(); > >>>> + statusCodeString = UtilValidate.isEmpty(status) ? > >>>> defaultStatusCodeString : status; > >>>> + } > >>>> + > >>>> + public MultivaluedMapContext<String, RequestMap> > >>>> getRequestMapMap() { > >>>> + return requestMapMap; > >>>> + } > >>>> + > >>>> + public Map<String, ConfigXMLReader.ViewMap> getViewMapMap() { > >>>> + return viewMapMap; > >>>> + } > >>>> + > >>>> + public String getStatusCodeString() { > >>>> + return statusCodeString; > >>>> + } > >>>> + > >>>> + public String getDefaultRequest() { > >>>> + return defaultRequest; > >>>> + } > >>>> + > >>>> + public void setStatusCodeString(String statusCodeString) { > >>>> + this.statusCodeString = statusCodeString; > >>>> + } > >>>> + > >>>> + public Map<String, ConfigXMLReader.Event> > >>>> getFirstVisitEventList() { > >>>> + return firstVisitEventList; > >>>> + } > >>>> + > >>>> + public Map<String, ConfigXMLReader.Event> > >>>> getPreprocessorEventList() { > >>>> + return preprocessorEventList; > >>>> + } > >>>> + > >>>> + public Map<String, ConfigXMLReader.Event> > >>>> getPostprocessorEventList() { > >>>> + return postprocessorEventList; > >>>> + } > >>>> + > >>>> + public String getProtectView() { > >>>> + return protectView; > >>>> + } > >>>> + } > >>>> > >>>> public static RequestHandler getRequestHandler(ServletContext > >>>> servletContext) { > >>>> RequestHandler rh = (RequestHandler) > >>>> servletContext.getAttribute("_REQUEST_HANDLER_"); > >>>> @@ -110,6 +178,56 @@ public class RequestHandler { > >>>> return null; > >>>> } > >>>> > >>>> + /** > >>>> + * Find a collection of request maps in {@code ccfg} matching > >> {@code > >>>> req}. > >>>> + * Otherwise fall back to matching the {@code defaultReq} field > in > >>>> {@code ccfg}. > >>>> + * > >>>> + * @param ccfg The controller containing the current > configuration > >>>> + * @param req The HTTP request to match > >>>> + * @return a collection of request maps which might be empty > >>>> + */ > >>>> + static Collection<RequestMap> resolveURI(ControllerConfig ccfg, > >>>> HttpServletRequest req) { > >>>> + Map<String, List<RequestMap>> requestMapMap = > >>>> ccfg.getRequestMapMap(); > >>>> + Map<String, ConfigXMLReader.ViewMap> viewMapMap = > >>>> ccfg.getViewMapMap(); > >>>> + String defaultRequest = ccfg.getDefaultRequest(); > >>>> + String path = req.getPathInfo(); > >>>> + String requestUri = getRequestUri(path); > >>>> + String viewUri = getOverrideViewUri(path); > >>>> + Collection<RequestMap> rmaps; > >>>> + if (requestMapMap.containsKey(requestUri) && > >>>> !viewMapMap.containsKey(viewUri)) { > >>>> + rmaps = requestMapMap.get(requestUri); > >>>> + } else if (defaultRequest != null) { > >>>> + rmaps = requestMapMap.get(defaultRequest); > >>>> + } else { > >>>> + rmaps = null; > >>>> + } > >>>> + return rmaps != null ? rmaps : Collections.emptyList(); > >>>> + } > >>>> + > >>>> + /** > >>>> + * Find the request map matching {@code method}. > >>>> + * Otherwise fall back to the one matching the "all" and "" > special > >>>> methods > >>>> + * in that respective order. > >>>> + * > >>>> + * @param method the HTTP method to match > >>>> + * @param rmaps the collection of request map candidates > >>>> + * @return a request map {@code Optional} > >>>> + */ > >>>> + static Optional<RequestMap> resolveMethod(String method, > >>>> Collection<RequestMap> rmaps) { > >>>> + for (RequestMap map : rmaps) { > >>>> + if (map.method.equalsIgnoreCase(method)) { > >>>> + return Optional.of(map); > >>>> + } > >>>> + } > >>>> + if (method.isEmpty()) { > >>>> + return Optional.empty(); > >>>> + } else if (method.equals("all")) { > >>>> + return resolveMethod("", rmaps); > >>>> + } else { > >>>> + return resolveMethod("all", rmaps); > >>>> + } > >>>> + } > >>>> + > >>>> public void doRequest(HttpServletRequest request, > >>>> HttpServletResponse response, String requestUri) throws > >>>> RequestHandlerException, RequestHandlerExceptionAllowExternalRequests > { > >>>> HttpSession session = request.getSession(); > >>>> Delegator delegator = (Delegator) request.getAttribute(" > >>>> delegator"); > >>>> @@ -125,20 +243,13 @@ public class RequestHandler { > >>>> long startTime = System.currentTimeMillis(); > >>>> HttpSession session = request.getSession(); > >>>> > >>>> - // get the controllerConfig once for this method so we don't > >>>> have to get it over and over inside the method > >>>> - ConfigXMLReader.ControllerConfig controllerConfig = > >>>> this.getControllerConfig(); > >>>> - Map<String, ConfigXMLReader.RequestMap> requestMapMap = null; > >>>> - String statusCodeString = null; > >>>> + // Parse controller config. > >>>> try { > >>>> - requestMapMap = controllerConfig.getRequestMapMap(); > >>>> - statusCodeString = controllerConfig.getStatusCode(); > >>>> + ccfg = new ControllerConfig(getControllerConfig()); > >>>> } catch (WebAppConfigurationException e) { > >>>> Debug.logError(e, "Exception thrown while parsing > >>>> controller.xml file: ", module); > >>>> throw new RequestHandlerException(e); > >>>> } > >>>> - if (UtilValidate.isEmpty(statusCodeString)) { > >>>> - statusCodeString = defaultStatusCodeString; > >>>> - } > >>>> > >>>> // workaround if we are in the root webapp > >>>> String cname = UtilHttp.getApplicationName(request); > >>>> @@ -153,50 +264,29 @@ public class RequestHandler { > >>>> } > >>>> } > >>>> > >>>> - String overrideViewUri = RequestHandler. > >>>> getOverrideViewUri(request.getPathInfo()); > >>>> - > >>>> - String requestMissingErrorMessage = "Unknown request [" + > >>>> defaultRequestUri + "]; this request does not exist or cannot be > called > >>>> directly."; > >>>> - ConfigXMLReader.RequestMap requestMap = null; > >>>> - if (defaultRequestUri != null) { > >>>> - requestMap = requestMapMap.get(defaultRequestUri); > >>>> - } > >>>> - // check for default request > >>>> - if (requestMap == null) { > >>>> - String defaultRequest; > >>>> - try { > >>>> - defaultRequest = > controllerConfig.getDefaultRequest(); > >>>> - } catch (WebAppConfigurationException e) { > >>>> - Debug.logError(e, "Exception thrown while parsing > >>>> controller.xml file: ", module); > >>>> - throw new RequestHandlerException(e); > >>>> - } > >>>> - if (defaultRequest != null) { // required! to avoid a > null > >>>> pointer exception and generate a requesthandler exception if default > >>>> request not found. > >>>> - requestMap = requestMapMap.get(defaultRequest); > >>>> - } > >>>> - } > >>>> - > >>>> - // check for override view > >>>> - if (overrideViewUri != null) { > >>>> - ConfigXMLReader.ViewMap viewMap; > >>>> - try { > >>>> - viewMap = getControllerConfig().getViewMapMap().get( > >>>> overrideViewUri); > >>>> - if (viewMap == null) { > >>>> - String defaultRequest = controllerConfig. > >>>> getDefaultRequest(); > >>>> - if (defaultRequest != null) { // required! to > avoid > >>>> a null pointer exception and generate a requesthandler exception if > >> default > >>>> request not found. > >>>> - requestMap = > requestMapMap.get(defaultRequest); > >>>> - } > >>>> - } > >>>> - } catch (WebAppConfigurationException e) { > >>>> - Debug.logError(e, "Exception thrown while parsing > >>>> controller.xml file: ", module); > >>>> - throw new RequestHandlerException(e); > >>>> + String requestMissingErrorMessage = "Unknown request [" > >>>> + + defaultRequestUri > >>>> + + "]; this request does not exist or cannot be called > >>>> directly."; > >>>> + > >>>> + String path = request.getPathInfo(); > >>>> + String requestUri = getRequestUri(path); > >>>> + String overrideViewUri = getOverrideViewUri(path); > >>>> + > >>>> + Collection<RequestMap> rmaps = resolveURI(ccfg, request); > >>>> + if (rmaps.isEmpty()) { > >>>> + if (throwRequestHandlerExceptionOnMissingLocalRequest) { > >>>> + throw new RequestHandlerException( > >>>> requestMissingErrorMessage); > >>>> + } else { > >>>> + throw new > RequestHandlerExceptionAllowExternalRequests(); > >>>> } > >>>> } > >>>> > >>>> - // if no matching request is found in the controller, > depending > >>>> on throwRequestHandlerExceptionOnMissingLocalRequest > >>>> - // we throw a RequestHandlerException or > >>>> RequestHandlerExceptionAllowExternalRequests > >>>> - if (requestMap == null) { > >>>> - if (throwRequestHandlerExceptionOnMissingLocalRequest) > >>>> throw new RequestHandlerException(requestMissingErrorMessage); > >>>> - else throw new RequestHandlerExceptionAllowEx > >>>> ternalRequests(); > >>>> - } > >>>> + String method = request.getMethod(); > >>>> + RequestMap requestMap = resolveMethod(method, > >>>> rmaps).orElseThrow(() -> { > >>>> + String msg = UtilProperties.getMessage("WebappUiLabels", > >>>> "RequestMethodNotMatchConfig", > >>>> + UtilMisc.toList(requestUri, method), > >>>> UtilHttp.getLocale(request)); > >>>> + return new MethodNotAllowedException(msg); > >>>> + }); > >>>> > >>>> String eventReturn = null; > >>>> if (requestMap.metrics != null && > >> requestMap.metrics.getThreshold() > >>>> != 0.0 && requestMap.metrics.getTotalEvents() > 3 && > >> requestMap.metrics.getThreshold() > >>>> < requestMap.metrics.getServiceRate()) { > >>>> @@ -210,7 +300,7 @@ public class RequestHandler { > >>>> // Check for chained request. > >>>> if (chain != null) { > >>>> String chainRequestUri = RequestHandler.getRequestUri( > >>>> chain); > >>>> - requestMap = requestMapMap.get(chainRequestUri); > >>>> + requestMap = ccfg.getRequestMapMap(). > >>>> getFirst(chainRequestUri); > >>>> if (requestMap == null) { > >>>> throw new RequestHandlerException("Unknown chained > >>>> request [" + chainRequestUri + "]; this request does not exist"); > >>>> } > >>>> @@ -234,18 +324,11 @@ public class RequestHandler { > >>>> // Check to make sure we are allowed to access this > request > >>>> directly. (Also checks if this request is defined.) > >>>> // If the request cannot be called, or is not defined, > >> check > >>>> and see if there is a default-request we can process > >>>> if (!requestMap.securityDirectRequest) { > >>>> - String defaultRequest; > >>>> - try { > >>>> - defaultRequest = controllerConfig. > >>>> getDefaultRequest(); > >>>> - } catch (WebAppConfigurationException e) { > >>>> - Debug.logError(e, "Exception thrown while parsing > >>>> controller.xml file: ", module); > >>>> - throw new RequestHandlerException(e); > >>>> - } > >>>> - if (defaultRequest == null || !requestMapMap.get( > >>>> defaultRequest).securityDirectRequest) { > >>>> + if (ccfg.getDefaultRequest() == null || > >>>> > >> > !ccfg.getRequestMapMap().getFirst(ccfg.getDefaultRequest()).securityDirectRequest) > >>>> { > >>>> // use the same message as if it was missing for > >>>> security reasons, ie so can't tell if it is missing or direct request > is > >>>> not allowed > >>>> throw new RequestHandlerException( > >>>> requestMissingErrorMessage); > >>>> } else { > >>>> - requestMap = requestMapMap.get(defaultRequest); > >>>> + requestMap = > ccfg.getRequestMapMap().getFirst(ccfg. > >>>> getDefaultRequest()); > >>>> } > >>>> } > >>>> // Check if we SHOULD be secure and are not. > >>>> @@ -288,7 +371,7 @@ public class RequestHandler { > >>>> String newUrl = RequestHandler.makeUrl(request, > >>>> response, urlBuf.toString()); > >>>> if (newUrl.toUpperCase().startsWith("HTTPS")) { > >>>> // if we are supposed to be secure, redirect > >>>> secure. > >>>> - callRedirect(newUrl, response, request, > >>>> statusCodeString); > >>>> + callRedirect(newUrl, response, request, > >>>> ccfg.getStatusCodeString()); > >>>> return; > >>>> } > >>>> } > >>>> @@ -333,63 +416,52 @@ public class RequestHandler { > >>>> if (Debug.infoOn()) > >>>> Debug.logInfo("This is the first request in this > >>>> visit." + showSessionId(request), module); > >>>> session.setAttribute("_FIRST_VISIT_EVENTS_", > >>>> "complete"); > >>>> - try { > >>>> - for (ConfigXMLReader.Event event: > controllerConfig. > >>>> getFirstVisitEventList().values()) { > >>>> - try { > >>>> - String returnString = > >> this.runEvent(request, > >>>> response, event, null, "firstvisit"); > >>>> - if (returnString == null || > >>>> "none".equalsIgnoreCase(returnString)) { > >>>> - interruptRequest = true; > >>>> - } else if > >> (!"success".equalsIgnoreCase(returnString)) > >>>> { > >>>> - throw new > >> EventHandlerException("First-Visit > >>>> event did not return 'success'."); > >>>> - } > >>>> - } catch (EventHandlerException e) { > >>>> - Debug.logError(e, module); > >>>> + for (ConfigXMLReader.Event event: > >>>> ccfg.getFirstVisitEventList().values()) { > >>>> + try { > >>>> + String returnString = this.runEvent(request, > >>>> response, event, null, "firstvisit"); > >>>> + if (returnString == null || > >>>> "none".equalsIgnoreCase(returnString)) { > >>>> + interruptRequest = true; > >>>> + } else if > >> (!"success".equalsIgnoreCase(returnString)) > >>>> { > >>>> + throw new > >> EventHandlerException("First-Visit > >>>> event did not return 'success'."); > >>>> } > >>>> + } catch (EventHandlerException e) { > >>>> + Debug.logError(e, module); > >>>> } > >>>> - } catch (WebAppConfigurationException e) { > >>>> - Debug.logError(e, "Exception thrown while parsing > >>>> controller.xml file: ", module); > >>>> - throw new RequestHandlerException(e); > >>>> } > >>>> } > >>>> > >>>> // Invoke the pre-processor (but NOT in a chain) > >>>> - try { > >>>> - for (ConfigXMLReader.Event event: controllerConfig. > >>>> getPreprocessorEventList().values()) { > >>>> - try { > >>>> - String returnString = this.runEvent(request, > >>>> response, event, null, "preprocessor"); > >>>> - if (returnString == null || > >>>> "none".equalsIgnoreCase(returnString)) { > >>>> - interruptRequest = true; > >>>> - } else if > >> (!"success".equalsIgnoreCase(returnString)) > >>>> { > >>>> - if > (!returnString.contains(":_protect_:")) > >> { > >>>> - throw new > >> EventHandlerException("Pre-Processor > >>>> event [" + event.invoke + "] did not return 'success'."); > >>>> - } else { // protect the view normally > >>>> rendered and redirec
