001/* 
002    Licensed to the Apache Software Foundation (ASF) under one
003    or more contributor license agreements.  See the NOTICE file
004    distributed with this work for additional information
005    regarding copyright ownership.  The ASF licenses this file
006    to you under the Apache License, Version 2.0 (the
007    "License"); you may not use this file except in compliance
008    with the License.  You may obtain a copy of the License at
009
010       http://www.apache.org/licenses/LICENSE-2.0
011
012    Unless required by applicable law or agreed to in writing,
013    software distributed under the License is distributed on an
014    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015    KIND, either express or implied.  See the License for the
016    specific language governing permissions and limitations
017    under the License.  
018 */
019package org.apache.wiki.providers;
020
021import org.apache.logging.log4j.LogManager;
022import org.apache.logging.log4j.Logger;
023import org.apache.wiki.api.core.Page;
024import org.apache.wiki.api.exceptions.ProviderException;
025
026import java.io.File;
027import java.io.IOException;
028import java.io.InputStream;
029import java.io.OutputStream;
030import java.nio.file.Files;
031import java.util.Properties;
032
033/**
034 *  Provides a simple directory based repository for Wiki pages.
035 *  <P>
036 *  All files have ".txt" appended to make life easier for those
037 *  who insist on using Windows or other software which makes assumptions
038 *  on the files contents based on its name.
039 *
040 */
041public class FileSystemProvider extends AbstractFileProvider {
042
043    private static final Logger LOG = LogManager.getLogger( FileSystemProvider.class );
044
045    /** All metadata is stored in a file with this extension. */
046    public static final String PROP_EXT = ".properties";
047
048    /**
049     *  {@inheritDoc}
050     */
051    @Override
052    public void putPageText( final Page page, final String text ) throws ProviderException {
053        try {
054            super.putPageText( page, text );
055            putPageProperties( page );
056        } catch( final IOException e ) {
057            LOG.error( "Saving failed" );
058        }
059    }
060
061    /**
062     *  Stores basic metadata to a file.
063     */
064    private void putPageProperties( final Page page ) throws IOException {
065        final Properties props = new Properties();
066        final String author = page.getAuthor();
067        final String changenote = page.getAttribute( Page.CHANGENOTE );
068        final String viewcount = page.getAttribute( Page.VIEWCOUNT );
069
070        if( author != null ) {
071            props.setProperty( Page.AUTHOR, author );
072        }
073
074        if( changenote != null ) {
075            props.setProperty( Page.CHANGENOTE, changenote );
076        }
077
078        if( viewcount != null ) {
079            props.setProperty( Page.VIEWCOUNT, viewcount );
080        }
081
082        // Get additional custom properties from page and add to props
083        getCustomProperties( page, props );
084
085        final File file = new File( getPageDirectory(), mangleName( page.getName() ) + PROP_EXT );
086        try( final OutputStream out = Files.newOutputStream( file.toPath() ) ) {
087            props.store( out, "JSPWiki page properties for page "+page.getName() );
088        }
089    }
090    
091    /**
092     *  Gets basic metadata from file.
093     */
094    private void getPageProperties( final Page page ) throws IOException {
095        final File file = new File( getPageDirectory(), mangleName( page.getName() ) + PROP_EXT );
096        if( file.exists() ) {
097            try( final InputStream in = Files.newInputStream( file.toPath() ) ) {
098                final Properties  props = new Properties();
099                props.load( in );
100                page.setAuthor( props.getProperty( Page.AUTHOR ) );
101
102                final String changenote = props.getProperty( Page.CHANGENOTE );
103                if( changenote != null ) {
104                    page.setAttribute( Page.CHANGENOTE, changenote );
105                }
106
107                final String viewcount = props.getProperty( Page.VIEWCOUNT );
108                if( viewcount != null ) {
109                    page.setAttribute( Page.VIEWCOUNT, viewcount );
110                }
111
112                // Set the props values to the page attributes
113                setCustomProperties( page, props );
114            }
115        }
116    }
117
118    /**
119     *  {@inheritDoc}
120     */
121    @Override
122    public Page getPageInfo( final String page, final int version ) throws ProviderException {
123        final Page p = super.getPageInfo( page, version );
124        if( p != null ) {
125            try {
126                getPageProperties( p );
127            } catch( final IOException e ) {
128                LOG.error( "Unable to read page properties", e );
129                throw new ProviderException( "Unable to read page properties, check logs." );
130            }
131        }
132
133        return p;
134    }
135
136    /**
137     *  {@inheritDoc}
138     */
139    @Override
140    public void deletePage( final String pageName) throws ProviderException {
141        super.deletePage( pageName );
142        final File file = new File( getPageDirectory(), mangleName(pageName)+PROP_EXT );
143        if( file.exists() ) {
144            file.delete();
145        }
146    }
147
148    /**
149     *  {@inheritDoc}
150     */
151    @Override
152    public void movePage( final String from, final String to ) throws ProviderException {
153        final File fromPage = findPage( from );
154        final File toPage = findPage( to );
155        fromPage.renameTo( toPage );
156    }
157
158}