/*
* Copyright 1999-2012 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.cobar.manager.dao.xml;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.xmlpull.mxp1.MXParser;
import org.xmlpull.mxp1_serializer.MXSerializer;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import com.alibaba.cobar.manager.dao.PropertyDAO;
import com.alibaba.cobar.manager.dataobject.xml.PropertyDO;
/**
* @author haiqing.zhuhq 2011-6-17
*/
public class PropertyDAOImple extends AbstractDAOImple implements PropertyDAO, InitializingBean {
private static final Logger logger = Logger.getLogger(PropertyDAOImple.class);
private static final ReentrantLock lock = new ReentrantLock();
private PropertyDO property;
public PropertyDAOImple() {
this.xpp = new MXParser();
this.xsl = new MXSerializer();
this.property = new PropertyDO();
}
public PropertyDO getProperty() {
return property;
}
public void setProperty(PropertyDO property) {
this.property = property;
}
private boolean read() {
FileInputStream is = null;
lock.lock();
try {
property.getStopTimes().clear();
is = new FileInputStream(xmlPath);
xpp.setInput(is, "UTF-8");
while (!(xpp.getEventType() == XmlPullParser.END_TAG && "pro".equals(xpp.getName()))) {
if (xpp.getEventType() == XmlPullParser.START_TAG && "property".equals(xpp.getName())) {
if ("stop_times".equals(xpp.getAttributeValue(0))) {
String value = xpp.nextText().trim();
String[] times = value.split(",");
for (int i = 0; i < times.length; i++) {
property.getStopTimes().add(Integer.parseInt(times[i].trim()));
}
Collections.sort(property.getStopTimes());
}
}
xpp.next();
}
is.close();
return true;
} catch (FileNotFoundException e) {
logger.error(e.getMessage(), e);
} catch (XmlPullParserException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
} finally {
lock.unlock();
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
return false;
}
private boolean write() {
FileOutputStream os = null;
lock.lock();
try {
if (!backup(xmlPath)) {
logger.error("property backup fail!");
}
os = new FileOutputStream(xmlPath);
xsl.setOutput(os, "UTF-8");
xsl.startDocument("UTF-8", null);
xsl.text("\n");
xsl.startTag(null, "pro");
xsl.text("\n");
String st = property.toString();
writeProperty("stop_times", st);
xsl.endTag(null, "pro");
xsl.endDocument();
os.close();
return true;
} catch (FileNotFoundException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
} finally {
lock.unlock();
}
if (null != os) {
try {
os.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
return false;
}
@Override
public void afterPropertiesSet() throws Exception {
xmlPath = xmlFileLoader.getFilePath();
if (null == xmlPath) {
logger.error("property xmlpath doesn't set!");
throw new IllegalArgumentException("property xmlpath doesn't set!");
} else {
if (xmlPath.endsWith(System.getProperty("file.separator"))) {
xmlPath = new StringBuilder(xmlPath).append("property.xml").toString();
} else {
xmlPath =
new StringBuilder(xmlPath).append(System.getProperty("file.separator"))
.append("property.xml")
.toString();
}
read();
}
}
@Override
public boolean addTime(int time) {
lock.lock();
try {
if (property.getStopTimes().contains(time)) {
return false;
}
property.getStopTimes().add(time);
Collections.sort(property.getStopTimes());
if (!write()) {
logger.error("Fail to add property!");
recovery(xmlPath);
read();
return false;
}
} finally {
lock.unlock();
}
return true;
}
@Override
public boolean deleteTime(int time) {
if (!property.getStopTimes().contains(time)) {
logger.warn("Time (" + time + ") to delete does not exist!");
return false;
}
property.getStopTimes().remove((Integer) time);
if (!write()) {
logger.error("Fail to delete property!");
recovery(xmlPath);
read();
return false;
}
return true;
}
}