Return-Path: Delivered-To: apmail-commons-user-archive@www.apache.org Received: (qmail 91252 invoked from network); 24 Mar 2009 22:14:46 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 24 Mar 2009 22:14:46 -0000 Received: (qmail 93866 invoked by uid 500); 24 Mar 2009 22:07:25 -0000 Delivered-To: apmail-commons-user-archive@commons.apache.org Received: (qmail 93764 invoked by uid 500); 24 Mar 2009 22:07:25 -0000 Mailing-List: contact user-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Commons Users List" Delivered-To: mailing list user@commons.apache.org Received: (qmail 93754 invoked by uid 99); 24 Mar 2009 22:07:25 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 24 Mar 2009 22:07:25 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of chrismfwrd@gmail.com designates 209.85.218.167 as permitted sender) Received: from [209.85.218.167] (HELO mail-bw0-f167.google.com) (209.85.218.167) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 24 Mar 2009 22:07:18 +0000 Received: by bwz11 with SMTP id 11so2276385bwz.42 for ; Tue, 24 Mar 2009 15:06:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=VJ1mp8ChHhzqjycsn1z6ophFoWPdhIaOoSs3X7eGtUE=; b=IqCmYqZDZzhzM+V+q0FzpnDqqXiIi+a4gKiYEjWqag7zbbg3vKSfZdAw/4lgNQr6BA ax2JmY4FSjdyG6LTT6vqiP8R9jq88gHVkEtNkZSUjroNEnkYIo/7gMOvJHW9cGBqoumi PXbMwd2jEFm7N0oAeCn8YGNdp5tqNrlTER7FQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=WqxMn0+PnR8O2+xVmw9LwmO3C3OP7yeeO/npsZ1xcblvdG2qbf9S3HahBWSctv8pPW lCLZhRUbZKJnHQRDlusG9ftHz977f+tvcx6fSiC4SyHswdZ9MZCWO/tZ38YB4rNM9Pnz XEnAZxM7Ib98nnQonxRlOjM7ZECCA5UKraHuM= MIME-Version: 1.0 Received: by 10.204.55.13 with SMTP id s13mr3076421bkg.180.1237932416827; Tue, 24 Mar 2009 15:06:56 -0700 (PDT) In-Reply-To: <49C9425D.9000004@oliver-heger.de> References: <8351c72a0903240221i1c5f792bpe39e8a8b1dd7a5bf@mail.gmail.com> <49C9425D.9000004@oliver-heger.de> Date: Tue, 24 Mar 2009 23:06:56 +0100 Message-ID: <8351c72a0903241506n6bed89fbr57e57dc40fa1b812@mail.gmail.com> Subject: Re: [commons-configuration] XMLConfiguration XPathExpressionEngine saving Lists error From: Christian Migowski To: Commons Users List Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Virus-Checked: Checked by ClamAV on apache.org thanks for your explanation! I browsed a little through the commons-configuration source, this issue also seems hard to solve to me because of the "generic" approach of commons-config and the "strict" structuring of XML. Here is how I solved this issue, it may be a reference for others facing similar problems or give you or the other developers an idea to solve it better in commons-config. As you can see the code assumes the last XML node to be the one that actually holds the list, which should be almost always what you want to do (in opposite to having multiple copies of the whole hierarchy). fileConfig is the XMLConfiguration (in my case it is a HierarchicalConfiguration obtained with configurationAt()) protected void saveOrAddFileList(String key, List value) { fileConfig.clearProperty(key); if (key.contains("/")) { int lastElementPos =3D key.lastIndexOf('/'); String parentElement =3D key.substring(0, lastElementPos); String newKey =3D parentElement + " " + key.substring(lastElementPos + 1); if (!fileConfig.getKeys(parentElement).hasNext()) { fileConfig.addProperty(" " + parentElement, ""); } fileConfig.addProperty(newKey, value); } else { fileConfig.addProperty(" " + key, value); } } christian! On Tue, Mar 24, 2009 at 9:28 PM, Oliver Heger wrote: > Christian Migowski schrieb: >> >> Hi, >> >> is this considered a bug: >> >> If I load a list with commons-configuration, then add new entries to >> that list and try to save it back to file, I get a >> "java.lang.IllegalArgumentException: prepareAdd: Passed in key must >> contain a whitespace!" exception. >> If I do not modify the list, saving works. >> If I remove entries from the list, saving works as well. >> >> Very simple demo-program: >> >> XML File: >> >> =C2=A0 eintrag 1 >> =C2=A0 eintrag 2 >> =C2=A0 eintrag 3 >> >> >> program: >> >> =C2=A0 =C2=A0public static void main(String[] args) { >> =C2=A0 =C2=A0 =C2=A0 =C2=A0XMLConfiguration masterconfig; >> =C2=A0 =C2=A0 =C2=A0 =C2=A0try { >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0masterconfig =3D new XMLConfigu= ration("democonfig.xml"); >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0masterconfig.setExpressionEngin= e(new XPathExpressionEngine()); >> >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0List test =3D mastercon= fig.getList("liste"); >> >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0masterconfig.setProperty("liste= ", test); //ok, no changes >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0masterconfig.save(); >> >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0test.remove("eintrag 2"); >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0masterconfig.setProperty("liste= ", test); //ok, one >> element is removed from file >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0masterconfig.save(); >> >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0test.add("neuer eintrag"); >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0masterconfig.setProperty("liste= ", test); //exception >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0masterconfig.save(); >> >> =C2=A0 =C2=A0 =C2=A0 =C2=A0} catch (Exception e) { >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0e.printStackTrace(); >> =C2=A0 =C2=A0 =C2=A0 =C2=A0} >> =C2=A0 =C2=A0} >> >> I think commons-configuration should work consistent on all this cases. >> >> best regards, >> christian! >> > At least I can explain what is happening here. > > When setProperty() is invoked with a list (or array) for the new property > value, it does the following: > - First it obtains the current values of the affected property (as a list= ). > - It then iterates over both the list with the new values and the list wi= th > the current values. > - As long as both lists have elements, the current elements are overridde= n > by the new ones. > - If at the end of the iteration the list with the current values has sti= ll > more values (i.e. the list with the new values had fewer elements than th= e > current values), the remaining elements are removed. > - Otherwise, if the list with the new values has more elements, the > additional values are added by calling addProperty(). > > It is the last step that causes the problems you see. If an > XPathExpressionEngine is used, addProperty() uses a special format for th= e > properties keys: a path to an existing node (to which new data is to be > added), followed by whitespace, followed by the name(s) of the new node(s= ) > to be added. This is because we only can interpret XPath expressions on a= n > existing nodes structure. > > Now, in your test program when you try to add a new element, addProperty(= ) > is called behind the scenes, but cannot interpret the passed in key. > > I agree that this is inconsistent, but unfortunately I don't know how to = fix > this. We might be able to work around the problem in some cases (e.g. if = the > property to be set has already some values, adding new elements can be > performed directly on the nodes structure). But when setProperty() is use= d > for adding a new property, I cannot see an easy solution. > > Oliver > > --------------------------------------------------------------------- > To unsubscribe, e-mail: user-unsubscribe@commons.apache.org > For additional commands, e-mail: user-help@commons.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: user-unsubscribe@commons.apache.org For additional commands, e-mail: user-help@commons.apache.org