001    ///////////////////////////////////////////////////////////////////////////////
002    // Copyright (c) 2006, Frank S. Nestel, All Rights Reserved.
003    //
004    // This library is free software; you can redistribute it and/or
005    // modify it under the terms of the GNU Lesser General Public
006    // License as published by the Free Software Foundation; either
007    // version 2.1 of the License, or (at your option) any later version.
008    //
009    // This library is distributed in the hope that it will be useful,
010    // but WITHOUT ANY WARRANTY; without even the implied warranty of
011    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012    // GNU General Public License for more details.
013    //
014    // You should have received a copy of the GNU Lesser General Public
015    // License along with this program; if not, write to the Free Software
016    // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
017    ///////////////////////////////////////////////////////////////////////////////
018    
019    package de.spieleck.app.turn;
020    
021    import java.io.File;
022    import java.io.PrintWriter;
023    import java.io.IOException;
024    import java.util.ArrayList;
025    import java.util.Iterator;
026    import java.util.regex.Pattern;
027    
028    import org.apache.log4j.Logger;
029    
030    /**
031     * Handle strange editable fileformats.
032     * <ul>
033     * <li>This is kind of a human editable compact serialization format.</li>
034     * <li>The Methods readRound() and writeRound() must work complementary.</li>
035     * <li>Finally: This has been factored out to be replaceable.</li>
036     * </ul>
037     *
038     * <p><a href="$URL: https://svn.sourceforge.net/svnroot/jtourney/src/de/spieleck/app/turn/FileProxy.java $">$URL: https://svn.sourceforge.net/svnroot/jtourney/src/de/spieleck/app/turn/FileProxy.java $</a></p>
039     *
040     * @author Frank S. Nestel
041     * @author $Author: nestefan $
042     * @version $Revision: 2 $ $Date: 2006-03-20 14:33:27 +0100 (Mo, 20 Mrz 2006) $ $Author: nestefan $
043     */
044    public class FileProxy
045    {
046        private final static Logger L = Logger.getLogger(FileProxy.class);
047    
048        public final static GameResult[] NOGAMERESULT =  new GameResult[0];
049    
050        public final static String SEP = ";";
051    
052        public final static Pattern SPLITTER = Pattern.compile("\\s*;\\s*");
053    
054        private ScoringMode scoringMode;
055    
056        private PlayerRegistry pRegistry;
057    
058        public FileProxy(ScoringMode scoringMode, PlayerRegistry pRegistry)
059        {
060            this.scoringMode = scoringMode;
061            this.pRegistry = pRegistry;
062        }
063    
064        public static String makeRoundName(int round)
065        {
066            return Run.ROUND + round;
067        }
068        
069        /** 
070         * Read in player file
071         */
072        public void readPlayers(LineSource ls)
073            throws IOException
074        {
075            String line;
076            while ( ( line = ls.line() ) != null )
077            {
078                String[] pieces = SPLITTER.split(line, 3);
079                if ( pieces.length < 3 )
080                {
081                    L.error("Illegal player line: <"+line+">.");
082                }
083                else
084                {
085                    pRegistry.registerPlayer(pieces[0], pieces[1], pieces[2]);
086                }
087            }
088            ls.close();
089        }
090    
091        /**
092         * Read one round.
093         */
094        public GameResult[] readRound(LineSource ls, boolean check)
095            throws Exception
096        {
097            ArrayList al = new ArrayList();
098            String line = ls.line();
099            while ( line != null )
100            {
101                String[] pieces = SPLITTER.split(line, 3);
102                if (L.isDebugEnabled() )
103                    L.debug(line+" "+pieces[0]+" "+pieces[1]+" "+pieces[2]); 
104                boolean active = !("-".equals(pieces[0].trim()));
105                int n = Integer.parseInt(pieces[1]);
106                int id = Integer.parseInt(pieces[2]);
107                if (L.isDebugEnabled() )
108                    L.debug("** "+n+" ("+line+")");
109                PlayerGameScore[] gameScores = new PlayerGameScore[n];
110                Player[] players = new Player[n];
111                for(int i = 0; i < n; i++)
112                {
113                    line = ls.line();
114                    pieces = SPLITTER.split(line, 2);
115                    int pid = Integer.parseInt(pieces[0]);
116                    gameScores[i] = scoringMode.parseRawScore(pieces[1]);
117                    players[i] = pRegistry.getPlayer(pid);
118                }
119                if ( active )
120                {
121                    if ( check )
122                    {
123                        String msg = scoringMode.checkScore(gameScores);
124                        if ( msg != null )
125                        {
126                            String msg2 = "checkScore: "+msg;
127                            L.error(msg2);
128                        }
129                    }
130                    // Renorm the game scores, i.e. for scoring relative to
131                    // the average player score or so.
132                    PlayerGameScore[] gameSc2
133                                        = scoringMode.adjustScore(gameScores);
134                    GameResult gr = new GameResult(id);
135                    for(int i = 0; i < n; i++)
136                    {
137                        Player p = players[i];
138                        gr.add(p, gameSc2[i]);
139                        p.setScore(scoringMode.add(p.getScore(),gameSc2[i]));
140                    }
141                    for(int i = 0; i < n; i++)
142                    {
143                        players[i].addResult(gr);
144                    }
145                    al.add(gr);
146                }
147                else
148                {
149                    L.info("Inactive game "+ls.getFName()+":"+id);
150                }
151                line = ls.line();
152            }
153            return (GameResult[]) al.toArray(NOGAMERESULT);
154        }
155    
156        /** 
157         * Write one round.
158         */
159        public void writeRound(PrintWriter bw, String msg, GameResult[] games)
160            throws IOException
161        {
162            bw.println(LineSource.COMMENTSTR+" "+msg);
163            for(int i = 0; i < games.length; i++)
164            {
165                GameResult g = games[i];
166                bw.println(LineSource.COMMENTSTR+"------------------------------");
167                bw.println("+"+SEP+g.size()+SEP+g.getId()
168                                +" "+LineSource.COMMENTSTR+"!!!");
169                Iterator<Player> it = g.players();
170                while ( it.hasNext() )
171                {
172                    Player p = it.next();
173                    PlayerScore score = g.getScore(p);
174                    bw.print(p.getId()+SEP+"\t"+score
175                                +" "+LineSource.COMMENTSTR+" "+p.getNameKurz());
176                    Iterator<GameResult> iter = p.results();
177                    while ( iter.hasNext() )
178                    {
179                        Iterator<Player> it3 = iter.next().players();
180                        while ( it3.hasNext() )
181                        {
182                            Player p3 = it3.next();
183                            if ( p3 != p )
184                                bw.print(" "+p3.getId());
185                        }
186                        bw.print("|");
187                    }
188                    bw.println();
189                }
190            }
191            bw.close();
192        }
193    
194    }