001    /*
002     * Copyright 2005 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    }