| /******************************************************************************* |
| * Copyright (c) 2007, 2018 Red Hat Inc. |
| * |
| * This program and the accompanying materials are made |
| * available under the terms of the Eclipse Public License 2.0 |
| * which is available at https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Red Hat - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.linuxtools.internal.rpm.ui.editor.actions; |
| |
| import java.text.MessageFormat; |
| import java.text.SimpleDateFormat; |
| import java.util.Calendar; |
| import java.util.Date; |
| import java.util.GregorianCalendar; |
| import java.util.Locale; |
| |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.BadPositionCategoryException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.ITypedRegion; |
| import org.eclipse.jface.text.Position; |
| import org.eclipse.linuxtools.changelog.core.IFormatterChangeLogContrib; |
| import org.eclipse.linuxtools.internal.rpm.ui.editor.SpecfileEditor; |
| import org.eclipse.linuxtools.internal.rpm.ui.editor.SpecfileLog; |
| import org.eclipse.linuxtools.internal.rpm.ui.editor.UiUtils; |
| import org.eclipse.linuxtools.internal.rpm.ui.editor.preferences.PreferenceConstants; |
| import org.eclipse.linuxtools.internal.rpm.ui.editor.scanners.SpecfilePartitionScanner; |
| import org.eclipse.linuxtools.rpm.ui.editor.parser.Specfile; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.preferences.ScopedPreferenceStore; |
| import org.osgi.framework.FrameworkUtil; |
| |
| public class SpecfileChangelogFormatter implements IFormatterChangeLogContrib { |
| |
| public final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("EEE MMM d yyyy"); //$NON-NLS-1$ |
| private static final String EMPTY_STRING = ""; //$NON-NLS-1$ |
| private IEditorPart changelog; |
| private IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, |
| FrameworkUtil.getBundle(SpecfileChangelogFormatter.class).getSymbolicName()); |
| |
| @Override |
| public String formatDateLine(String authorName, String authorEmail) { |
| String dateLine; |
| Specfile specfile = getParsedSpecfile(); |
| String epoch = specfile.getEpoch() == -1 ? EMPTY_STRING : (specfile.getEpoch() + ":"); //$NON-NLS-1$ |
| String version = specfile.getVersion(); |
| String release = specfile.getRelease(); |
| |
| // remove the dist macro if it exist in the release string. |
| release = release.replaceAll("\\%\\{\\?dist\\}", EMPTY_STRING); //$NON-NLS-1$ |
| |
| // default format |
| dateLine = MessageFormat.format("* {0} {1} <{2}> {3}{4}-{5}", formatTodaysDate(), authorName, //$NON-NLS-1$ |
| authorEmail, epoch, version, release); |
| |
| String format = store.getString(PreferenceConstants.P_CHANGELOG_ENTRY_FORMAT); |
| if (format.equals(PreferenceConstants.P_CHANGELOG_ENTRY_FORMAT_VERSIONED_WITH_SEPARATOR)) { |
| dateLine = MessageFormat.format("* {0} {1} <{2}> - {3}{4}-{5}", formatTodaysDate(), //$NON-NLS-1$ |
| authorName, authorEmail, epoch, version, release); |
| |
| } else if (format.equals(PreferenceConstants.P_CHANGELOG_ENTRY_FORMAT_UNVERSIONED)) { |
| dateLine = MessageFormat.format("* {0} {1} <{2}>", formatTodaysDate(), authorName, authorEmail); //$NON-NLS-1$ |
| } |
| |
| return UiUtils.resolveDefines(specfile, dateLine); |
| |
| } |
| |
| protected Specfile getParsedSpecfile() { |
| if (changelog == null) { |
| changelog = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); |
| } |
| if (changelog instanceof SpecfileEditor) { |
| SpecfileEditor specEditor = (SpecfileEditor) changelog; |
| return specEditor.getSpecfile(); |
| } |
| return null; |
| } |
| |
| private String formatTodaysDate() { |
| Calendar cal = new GregorianCalendar(); |
| cal.setTime(new Date()); |
| // Get default locale |
| Locale defaultLocale = Locale.getDefault(); |
| Locale.setDefault(new Locale(store.getString(PreferenceConstants.P_CHANGELOG_LOCAL))); |
| String date = SIMPLE_DATE_FORMAT.format(new Date()); |
| Locale.setDefault(defaultLocale); |
| return date; |
| } |
| |
| @Override |
| public String mergeChangelog(String dateLine, String functionGuess, String defaultContent, IEditorPart changelog, |
| String changeLogLocation, String fileLocation) { |
| if (changelog instanceof SpecfileEditor) { |
| SpecfileEditor specEditor = (SpecfileEditor) changelog; |
| IDocument doc = specEditor.getDocumentProvider().getDocument(specEditor.getEditorInput()); |
| String[] positionCategories = doc.getPositionCategories(); |
| String contentTypesPositionCategory = null; |
| |
| // there is some random number suffix to the category positions, |
| // we need to find the one we want |
| for (String positionCategory : positionCategories) { |
| if (positionCategory.startsWith("__content_types_category")) {//$NON-NLS-1$ |
| contentTypesPositionCategory = positionCategory; |
| } |
| } |
| |
| if (contentTypesPositionCategory != null) { |
| try { |
| Position[] sectionPositions = doc.getPositions(contentTypesPositionCategory); |
| ITypedRegion changelogPartition = null; |
| for (Position position : sectionPositions) { |
| int offset = position.getOffset(); |
| |
| ITypedRegion partition = doc.getPartition(offset); |
| if (partition.getType().equals(SpecfilePartitionScanner.SPEC_CHANGELOG)) { |
| changelogPartition = partition; |
| } |
| |
| } |
| // Temporary buffer for changelog text |
| StringBuilder buf = new StringBuilder(); |
| String changelogText = EMPTY_STRING; |
| String[] changelogLines = {}; |
| int offset = doc.getLength(); |
| int length = 0; |
| |
| // there was no changelog partition add it. |
| if (changelogPartition == null) { |
| |
| // make sure there are at least 2 newlines before |
| // the changelog section |
| String endString = doc.get(doc.getLength() - 2, 2); |
| if (endString.charAt(0) != '\n') { |
| buf.append('\n'); |
| } |
| if (endString.charAt(1) != '\n') { |
| buf.append('\n'); |
| } |
| |
| buf.append("%changelog\n"); //$NON-NLS-1$ |
| |
| // or get the old text and add the header |
| } else { |
| offset = changelogPartition.getOffset(); |
| length = changelogPartition.getLength(); |
| changelogText = doc.get(offset, length); |
| |
| // get old changelog text |
| changelogLines = changelogText.split("\n"); //$NON-NLS-1$ |
| // add the %changelog header |
| buf.append(changelogLines[0]).append('\n'); |
| } |
| |
| // now add the entry stub |
| buf.append(dateLine); |
| buf.append('\n'); |
| buf.append("- \n"); //$NON-NLS-1$ |
| |
| // set the cursor at the end of the entry, |
| // count back 2 '\n's |
| int newCursorOffset = offset + buf.length() - 1; |
| for (int i = 1; i < changelogLines.length; i++) { |
| buf.append('\n').append(changelogLines[i]); |
| } |
| |
| // always terminate the file with a new line |
| if (changelogLines.length > 0) { |
| buf.append('\n'); |
| } |
| |
| doc.replace(offset, length, buf.toString()); |
| |
| specEditor.selectAndReveal(newCursorOffset, 0); |
| specEditor.setFocus(); |
| } catch (BadPositionCategoryException | BadLocationException e) { |
| SpecfileLog.logError(e); |
| } |
| } |
| } |
| return EMPTY_STRING; |
| } |
| |
| } |