001    /*
002     * Copyright 2010 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.vafer.jdeb.changes;
017    
018    import java.io.BufferedReader;
019    import java.io.BufferedWriter;
020    import java.io.IOException;
021    import java.io.InputStream;
022    import java.io.InputStreamReader;
023    import java.io.OutputStream;
024    import java.io.OutputStreamWriter;
025    import java.text.DateFormat;
026    import java.text.ParseException;
027    import java.text.SimpleDateFormat;
028    import java.util.ArrayList;
029    import java.util.Collection;
030    import java.util.Date;
031    import java.util.Locale;
032    
033    import org.vafer.jdeb.descriptors.PackageDescriptor;
034    
035    /**
036     * Gets the changes from a changes file. The first entry are the current changes.
037     * The release line will be added. Example:
038     
039    release date=22:13 19.08.2007,version=1.5+r90114,urgency=low,by=Torsten Curdt <torsten@vafer.org>
040      * debian changes support
041    release date=20:13 17.08.2007,version=1.4+r89114,urgency=low,by=Torsten Curdt <torsten@vafer.org>
042      * debian changes support
043    
044     * @author Torsten Curdt <tcurdt@vafer.org>
045     */
046    public final class TextfileChangesProvider implements ChangesProvider {
047    
048        private final ChangeSet[] changeSets;
049        
050        public TextfileChangesProvider( final InputStream pInput, final PackageDescriptor pDescriptor ) throws IOException, ParseException {        
051                    
052            final BufferedReader reader = new BufferedReader(new InputStreamReader(pInput));
053    
054            final DateFormat tdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH); // RFC 2822 format
055            final DateFormat sdf = ChangeSet.createDateForma();
056    
057            String packageName = pDescriptor.get("Package");
058            String version = pDescriptor.get("Version");
059            Date date = tdf.parse(pDescriptor.get("Date"));
060            String distribution = pDescriptor.get("Distribution");
061            String urgency = pDescriptor.get("Urgency");
062            String changedBy = pDescriptor.get("Maintainer");
063            final Collection changesColl = new ArrayList();
064            final Collection changeSetColl = new ArrayList();
065    
066            
067            while(true) {
068                final String line = reader.readLine();
069                if (line == null) {
070                    final String[] changes = (String[]) changesColl.toArray(new String[changesColl.size()]);
071                    final ChangeSet changeSet = new ChangeSet(packageName, version, date, distribution, urgency, changedBy, changes);
072                    changeSetColl.add(changeSet);
073                    break;
074                }
075                
076                if (line.startsWith("release ")) {
077    
078                    if (changesColl.size() > 0) {
079                        final String[] changes = (String[]) changesColl.toArray(new String[changesColl.size()]);
080                        final ChangeSet changeSet = new ChangeSet(packageName, version, date, distribution, urgency, changedBy, changes);
081                        changeSetColl.add(changeSet);
082                        changesColl.clear();
083                    }
084                    
085                    final String[] tokens = line.substring("release ".length()).split(",");
086                    for (int i = 0; i < tokens.length; i++) {
087                        final String token = tokens[i].trim();
088                        final String[] lr = token.split("=");
089                        final String key = lr[0];
090                        final String value = lr[1];
091                        
092                        if ("urgency".equals(key)) {
093                            urgency = value;
094                        } else if ("by".equals(key)) {
095                            changedBy = value;
096                        } else if ("date".equals(key)) {
097                            date = sdf.parse(value);
098                        } else if ("version".equals(key)) {
099                            version = value;
100                        } else if ("distribution".equals(key)) {
101                            distribution = value;
102                        }
103                    }
104                    continue;
105                }
106                
107                if (line.startsWith(" * ")) {
108                    changesColl.add(line.substring(" * ".length()));
109                    continue;
110                }
111                
112                throw new ParseException("Unknown line syntax [" + line + "]", 0);
113            }
114            
115            reader.close();
116            
117            changeSets = (ChangeSet[]) changeSetColl.toArray(new ChangeSet[changeSetColl.size()]);      
118        }
119        
120        public void save( final OutputStream pOutput ) throws IOException {
121            final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(pOutput));
122            
123            final DateFormat df = ChangeSet.createDateForma();
124            
125            for (int i = 0; i < changeSets.length; i++) {
126                final ChangeSet changeSet = changeSets[i];
127                
128                writer.write("release ");
129                writer.write("date=" + df.format(changeSet.getDate()) + ",");
130                writer.write("version=" + changeSet.getVersion() + ",");
131                writer.write("urgency=" + changeSet.getUrgency() + ",");
132                writer.write("by=" + changeSet.getChangedBy() + ",");
133                writer.write("distribution=" + changeSet.getDistribution());
134                writer.write("\n");
135    
136                final String[] changes = changeSet.getChanges();
137                for (int j = 0; j < changes.length; j++) {
138                    writer.write(" * ");
139                    writer.write(changes[j]);
140                    writer.write("\n");
141                }
142            }
143            
144            writer.close();
145        }
146        
147        public ChangeSet[] getChangesSets() {
148            return changeSets;
149        }
150    
151    }